mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 23:01:30 +00:00
53 lines
1.7 KiB
TypeScript
53 lines
1.7 KiB
TypeScript
import { execSync, spawn } from "child_process";
|
|
import { platform } from "os";
|
|
import { isWaylandSession } from "./clipboard-image.js";
|
|
|
|
export function copyToClipboard(text: string): void {
|
|
const p = platform();
|
|
const options = { input: text, timeout: 5000 };
|
|
|
|
try {
|
|
if (p === "darwin") {
|
|
execSync("pbcopy", options);
|
|
} else if (p === "win32") {
|
|
execSync("clip", options);
|
|
} else {
|
|
// Linux - try wl-copy for Wayland, fall back to xclip/xsel for X11
|
|
const isWayland = isWaylandSession();
|
|
if (isWayland) {
|
|
try {
|
|
// Verify wl-copy exists (spawn errors are async and won't be caught)
|
|
execSync("which wl-copy", { stdio: "ignore" });
|
|
// wl-copy with execSync hangs due to fork behavior; use spawn instead
|
|
const proc = spawn("wl-copy", [], { stdio: ["pipe", "ignore", "ignore"] });
|
|
proc.stdin.on("error", () => {
|
|
// Ignore EPIPE errors if wl-copy exits early
|
|
});
|
|
proc.stdin.write(text);
|
|
proc.stdin.end();
|
|
proc.unref();
|
|
} catch {
|
|
// Fall back to xclip/xsel (works on XWayland)
|
|
try {
|
|
execSync("xclip -selection clipboard", options);
|
|
} catch {
|
|
execSync("xsel --clipboard --input", options);
|
|
}
|
|
}
|
|
} else {
|
|
try {
|
|
execSync("xclip -selection clipboard", options);
|
|
} catch {
|
|
execSync("xsel --clipboard --input", options);
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
const msg = error instanceof Error ? error.message : String(error);
|
|
if (p === "linux") {
|
|
const tools = isWaylandSession() ? "wl-copy, xclip, or xsel" : "xclip or xsel";
|
|
throw new Error(`Failed to copy to clipboard. Install ${tools}: ${msg}`);
|
|
}
|
|
throw new Error(`Failed to copy to clipboard: ${msg}`);
|
|
}
|
|
}
|