@every-env/cli
Version:
Multi-agent orchestrator for AI-powered development workflows
51 lines • 2.16 kB
JavaScript
import { execFile } from "child_process";
import { promisify } from "util";
import shellEscape from "shell-escape";
const execFileAsync = promisify(execFile);
export async function execCommand(command, args = [], options = {}) {
const { interactive = true, cwd = process.cwd(), env = process.env } = options;
if (interactive) {
// For interactive mode, we need to use spawn instead of execFile
const { spawn } = await import("child_process");
// When using shell, we need to construct a single command string
// and properly escape arguments using shell-escape
const shellCommand = args.length > 0
? shellEscape([command, ...args])
: command;
// For zsh, we need to make it interactive to load aliases
const shellArgs = process.env.SHELL?.includes('zsh') ? ['-i', '-c', shellCommand] : ['-c', shellCommand];
const child = spawn(process.env.SHELL || '/bin/bash', shellArgs, {
stdio: "inherit",
cwd,
env,
});
return new Promise((resolve, reject) => {
child.on("close", (code) => {
if (code === 0) {
resolve();
}
else {
reject(new Error(`Command failed with exit code ${code}`));
}
});
child.on("error", reject);
});
}
else {
const { stdout, stderr } = await execFileAsync(command, args, { cwd, env });
if (stdout)
console.log(stdout);
if (stderr)
console.error(stderr);
}
}
/**
* Execute a command and capture its stdout/stderr without spawning an interactive shell.
* Returns stdout as a string. Throws on non-zero exit status.
*/
export async function execCapture(command, args = [], options = {}) {
const { cwd = process.cwd(), env = process.env } = options;
const { stdout, stderr } = await execFileAsync(command, args, { cwd, env });
return { stdout: stdout?.toString?.() ?? String(stdout ?? ''), stderr: stderr?.toString?.() ?? String(stderr ?? '') };
}
//# sourceMappingURL=exec.js.map