diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 2af5b21152c..c2cf8904a91 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -442,7 +442,7 @@ function App() { title: "Open docs", value: "docs.open", onSelect: () => { - open("https://opencode.ai/docs").catch(() => {}) + open("https://opencode.ai/docs").catch(() => { }) dialog.clear() }, category: "System", @@ -451,7 +451,7 @@ function App() { title: "Open WebUI", value: "webui.open", onSelect: () => { - open(sdk.url).catch(() => {}) + open(sdk.url).catch(() => { }) dialog.clear() }, category: "System", @@ -629,8 +629,10 @@ function App() { renderer.writeOut(finalOsc52) await Clipboard.copy(text) .then(() => toast.show({ message: "Copied to clipboard", variant: "info" })) - .catch(toast.error) - renderer.clearSelection() + .catch((error) => { + toast.error(error) + renderer.clearSelection() + }) } }} > diff --git a/packages/opencode/src/cli/cmd/tui/util/clipboard.ts b/packages/opencode/src/cli/cmd/tui/util/clipboard.ts index 9c91cf3055a..8e8b8c5bc2d 100644 --- a/packages/opencode/src/cli/cmd/tui/util/clipboard.ts +++ b/packages/opencode/src/cli/cmd/tui/util/clipboard.ts @@ -52,7 +52,7 @@ export namespace Clipboard { } } - const text = await clipboardy.read().catch(() => {}) + const text = await clipboardy.read().catch(() => { }) if (text) { return { data: text, mime: "text/plain" } } @@ -70,13 +70,15 @@ export namespace Clipboard { } if (os === "linux") { - if (process.env["WAYLAND_DISPLAY"] && Bun.which("wl-copy")) { + const isWayland = !!process.env["WAYLAND_DISPLAY"] + if (isWayland && Bun.which("wl-copy")) { console.log("clipboard: using wl-copy") return async (text: string) => { const proc = Bun.spawn(["wl-copy"], { stdin: "pipe", stdout: "ignore", stderr: "ignore" }) proc.stdin.write(text) proc.stdin.end() - await proc.exited.catch(() => {}) + const code = await proc.exited.catch(() => 1) + if (code !== 0) throw new Error("wl-copy failed to copy to clipboard") } } if (Bun.which("xclip")) { @@ -89,7 +91,8 @@ export namespace Clipboard { }) proc.stdin.write(text) proc.stdin.end() - await proc.exited.catch(() => {}) + const code = await proc.exited.catch(() => 1) + if (code !== 0) throw new Error("xclip failed to copy to clipboard") } } if (Bun.which("xsel")) { @@ -102,9 +105,18 @@ export namespace Clipboard { }) proc.stdin.write(text) proc.stdin.end() - await proc.exited.catch(() => {}) + const code = await proc.exited.catch(() => 1) + if (code !== 0) throw new Error("xsel failed to copy to clipboard") } } + + return async () => { + throw new Error( + isWayland + ? "No clipboard tool found. Please install 'wl-clipboard'." + : "No clipboard tool found. Please install 'xclip' or 'xsel'.", + ) + } } if (os === "win32") { @@ -112,13 +124,13 @@ export namespace Clipboard { return async (text: string) => { // need to escape backticks because powershell uses them as escape code const escaped = text.replace(/"/g, '""').replace(/`/g, "``") - await $`powershell -NonInteractive -NoProfile -Command "Set-Clipboard -Value \"${escaped}\""`.nothrow().quiet() + await $`powershell -NonInteractive -NoProfile -Command "Set-Clipboard -Value \"${escaped}\""`.quiet() } } console.log("clipboard: no native support") return async (text: string) => { - await clipboardy.write(text).catch(() => {}) + await clipboardy.write(text) } })