const { execSync } = require("child_process");
function sanitizedEnv(base = process.env) {
const env = { ...base };
delete env.TMUX;
delete env.TMUX_PANE;
return env;
}
const SOCKET_FLAG_RE = /(?:^|\s)-(?:L|S)\s+(\S+)/;
function isDelegatedCommand(cmdPrefix) {
return !/^\s*tmux(\s|$)/.test(cmdPrefix);
}
function resolveSocketName(cmdPrefix) {
const match = cmdPrefix.match(SOCKET_FLAG_RE);
return match ? match[1] : null;
}
function assertIsolated(cmdPrefix, args) {
const delegated = isDelegatedCommand(cmdPrefix);
const socket = resolveSocketName(cmdPrefix);
if (delegated || (socket && socket !== "default")) return;
throw new Error(
`tmux-safety: refusing "${cmdPrefix} ${args}" — no explicit -L/-S test ` +
`socket and not a delegated runner (e.g. podman exec ... tmux). This ` +
`would target the host's default tmux server. See issue #183.`,
);
}
function buildInvocation(cmdPrefix, args) {
assertIsolated(cmdPrefix, args);
return {
command: `${cmdPrefix} ${args}`,
options: { stdio: "pipe", env: sanitizedEnv() },
};
}
function createTmuxRunner(
defaultSocket,
{ envVar = "MOBUX_TEST_TMUX", exec = execSync } = {},
) {
const cmdPrefix =
(envVar && process.env[envVar]) || `tmux -L ${defaultSocket}`;
return (args) => {
const { command, options } = buildInvocation(cmdPrefix, args);
return exec(command, options);
};
}
module.exports = {
createTmuxRunner,
sanitizedEnv,
assertIsolated,
buildInvocation,
};