diff --git a/packages/opencode/src/cli/cmd/tui/util/clipboard.ts b/packages/opencode/src/cli/cmd/tui/util/clipboard.ts index 9c91cf3055a..da98583e460 100644 --- a/packages/opencode/src/cli/cmd/tui/util/clipboard.ts +++ b/packages/opencode/src/cli/cmd/tui/util/clipboard.ts @@ -5,6 +5,8 @@ import { lazy } from "../../../../util/lazy.js" import { tmpdir } from "os" import path from "path" +export const escapePowerShellValue = (text: string) => text.replace(/`/g, "``").replace(/"/g, '""') + export namespace Clipboard { export interface Content { data: string @@ -110,8 +112,7 @@ export namespace Clipboard { if (os === "win32") { console.log("clipboard: using powershell") return async (text: string) => { - // need to escape backticks because powershell uses them as escape code - const escaped = text.replace(/"/g, '""').replace(/`/g, "``") + const escaped = escapePowerShellValue(text) await $`powershell -NonInteractive -NoProfile -Command "Set-Clipboard -Value \"${escaped}\""`.nothrow().quiet() } } diff --git a/packages/opencode/test/clipboard.test.ts b/packages/opencode/test/clipboard.test.ts new file mode 100644 index 00000000000..af3b660b783 --- /dev/null +++ b/packages/opencode/test/clipboard.test.ts @@ -0,0 +1,10 @@ +import { describe, expect, it } from "bun:test" +import { escapePowerShellValue } from "../src/cli/cmd/tui/util/clipboard" + +describe("escapePowerShellValue", () => { + it("escapes backticks and double quotes for PowerShell", () => { + const input = 'back`tick"quote' + const escaped = escapePowerShellValue(input) + expect(escaped).toBe('back``tick""quote') + }) +})