@earendil-works/pi-coding-agent
Version:
Coding agent CLI with read, bash, edit, write tools and session management
52 lines • 2.22 kB
JavaScript
import { spawn } from "node:child_process";
/** Undefined means the command failed; an empty buffer is a successful result. */
export function runClipboardCommand(command, args, options) {
return new Promise((resolve) => {
// Clipboard writers can daemonize. Do not give them output pipes to retain.
// Detach on POSIX so the daemon leaves pi's process group and Ctrl+Z suspend
// (SIGTSTP to the group) does not stop the clipboard owner (#11179).
// Run from / (the current drive root on Windows): clipboard tools ignore the cwd, and WSL cannot start
// Windows executables (powershell.exe) when the cwd's \\wsl.localhost\... path
// exceeds MAX_PATH (#11592). This also keeps daemons from pinning pi's cwd.
const child = spawn(command, args, {
stdio: ["pipe", options?.input === undefined ? "pipe" : "ignore", "ignore"],
cwd: "/",
detached: process.platform !== "win32",
windowsHide: true,
});
const chunks = [];
let length = 0;
let settled = false;
const finish = (result) => {
if (settled)
return;
settled = true;
clearTimeout(timer);
resolve(result);
};
const abort = () => {
child.kill("SIGKILL");
child.stdout?.destroy();
child.stdin?.destroy();
finish(undefined);
};
const timer = setTimeout(abort, options?.timeoutMs ?? 3000);
child.on("error", () => finish(undefined));
child.on("close", (code) => {
if (!settled)
finish(code === 0 ? Buffer.concat(chunks, length) : undefined);
});
child.stdout?.on("data", (chunk) => {
if (settled)
return;
length += chunk.length;
if (length > (options?.maxBufferBytes ?? 50 * 1024 * 1024))
abort();
else
chunks.push(chunk);
});
child.stdin?.on("error", () => { }); // A writer may exit before consuming all input.
child.stdin?.end(options?.input);
});
}
//# sourceMappingURL=clipboard-command.js.map