diff --git a/apps/web/src/components/chat/ProposedPlanCard.tsx b/apps/web/src/components/chat/ProposedPlanCard.tsx
index c8956b9cfa..fc52c33225 100644
--- a/apps/web/src/components/chat/ProposedPlanCard.tsx
+++ b/apps/web/src/components/chat/ProposedPlanCard.tsx
@@ -25,6 +25,7 @@ import {
} from "../ui/dialog";
import { toastManager } from "../ui/toast";
import { readNativeApi } from "~/nativeApi";
+import { useCopyToClipboard } from "~/hooks/useCopyToClipboard";
export const ProposedPlanCard = memo(function ProposedPlanCard({
planMarkdown,
@@ -39,6 +40,15 @@ export const ProposedPlanCard = memo(function ProposedPlanCard({
const [isSaveDialogOpen, setIsSaveDialogOpen] = useState(false);
const [savePath, setSavePath] = useState("");
const [isSavingToWorkspace, setIsSavingToWorkspace] = useState(false);
+ const { copyToClipboard, isCopied } = useCopyToClipboard({
+ onError: (error) => {
+ toastManager.add({
+ type: "error",
+ title: "Could not copy plan",
+ description: error instanceof Error ? error.message : "An error occurred while copying.",
+ });
+ },
+ });
const savePathInputId = useId();
const title = proposedPlanTitle(planMarkdown) ?? "Proposed plan";
const lineCount = planMarkdown.split("\n").length;
@@ -54,6 +64,10 @@ export const ProposedPlanCard = memo(function ProposedPlanCard({
downloadPlanAsTextFile(downloadFilename, saveContents);
};
+ const handleCopyPlan = () => {
+ copyToClipboard(saveContents);
+ };
+
const openSaveDialog = () => {
if (!workspaceRoot) {
toastManager.add({
@@ -127,6 +141,9 @@ export const ProposedPlanCard = memo(function ProposedPlanCard({
+