← Files RivetARCHIVED FILE
node_modules/rivet-design/dist/utils/loginShellPath.js
4.54 KB · Nov 5, 2026 · 12:09 UTC
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resetLoginShellPathForTests = exports.ensureLoginShellPath = exports.mergePathValues = exports.loginShellPath = exports.isBinaryOnPathValue = void 0;
const child_process_1 = require("child_process");
const subprocessEnvironment_1 = require("./subprocessEnvironment");
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const logger_1 = require("./logger");
const log = (0, logger_1.createLogger)('LoginShellPath');
const SENTINEL = '__RIVET_PATH__';
const rcFileForShell = (shell) => {
const name = path_1.default.basename(shell);
if (name === 'zsh')
return '~/.zshrc';
if (name === 'bash')
return '~/.bashrc';
return null;
};
const defaultExec = (shell, args) => (0, child_process_1.execFileSync)(shell, args, {
timeout: 4_000,
env: (0, subprocessEnvironment_1.subprocessEnvironment)('verifier'),
stdio: ['ignore', 'pipe', 'ignore'],
encoding: 'utf8',
});
const PRINT_PATH = `printf "%s%s%s" "${SENTINEL}" "$PATH" "${SENTINEL}"`;
const DEFAULT_GOAL_BINARIES = ['claude', 'node'];
const isBinaryOnPathValue = (binary, pathValue) => pathValue.split(':').some((dir) => {
if (!dir)
return false;
try {
fs_1.default.accessSync(path_1.default.join(dir, binary), fs_1.default.constants.X_OK);
return true;
}
catch {
return false;
}
});
exports.isBinaryOnPathValue = isBinaryOnPathValue;
const loginShellPath = (options) => {
if (process.platform === 'win32')
return null;
const shell = options?.shell ?? process.env.SHELL ?? '/bin/zsh';
const exec = options?.exec ?? defaultExec;
const basePath = options?.basePath ?? process.env.PATH ?? '';
const goalBinaries = options?.goalBinaries ?? DEFAULT_GOAL_BINARIES;
const rcFile = rcFileForShell(shell);
const probes = [
['-lc', PRINT_PATH],
...(rcFile
? [['-lc', `. ${rcFile} >/dev/null 2>&1 || true; ${PRINT_PATH}`]]
: []),
['-ilc', PRINT_PATH],
];
let union = '';
for (const args of probes) {
let value;
try {
const output = exec(shell, args);
value = output
.match(new RegExp(`${SENTINEL}([\\s\\S]*?)${SENTINEL}`))?.[1]
?.trim();
}
catch (error) {
log.warn(`login-shell PATH probe (${args[0]}) failed for ${shell}`, error instanceof Error ? error.message : error);
continue;
}
if (!value)
continue;
union = union ? (0, exports.mergePathValues)(union, value) : value;
if (areBinariesOnPathValue(goalBinaries, (0, exports.mergePathValues)(basePath, union))) {
break;
}
}
return union || null;
};
exports.loginShellPath = loginShellPath;
const areBinariesOnPathValue = (binaries, pathValue) => binaries.every((binary) => (0, exports.isBinaryOnPathValue)(binary, pathValue));
const mergePathValues = (base, extra) => {
const baseDirs = base.split(':').filter(Boolean);
const seen = new Set(baseDirs);
const additions = extra.split(':').filter((dir) => dir && !seen.has(dir));
return [...baseDirs, ...additions].join(':');
};
exports.mergePathValues = mergePathValues;
const APPLIED_ENV_FLAG = 'RIVET_LOGIN_SHELL_PATH_APPLIED';
let enriched = false;
const ensureLoginShellPath = (options) => {
if (enriched)
return;
enriched = true;
if (process.env[APPLIED_ENV_FLAG] === '1')
return;
const current = process.env.PATH ?? '';
if (areBinariesOnPathValue(options?.goalBinaries ?? DEFAULT_GOAL_BINARIES, current)) {
process.env[APPLIED_ENV_FLAG] = '1';
return;
}
const shellPath = (0, exports.loginShellPath)({ ...options, basePath: current });
if (!shellPath)
return;
process.env[APPLIED_ENV_FLAG] = '1';
const merged = (0, exports.mergePathValues)(current, shellPath);
if (merged !== current) {
log.info(`merged ${merged.split(':').length - current.split(':').filter(Boolean).length} login-shell PATH entries into the server environment`);
process.env.PATH = merged;
}
};
exports.ensureLoginShellPath = ensureLoginShellPath;
const resetLoginShellPathForTests = () => {
enriched = false;
delete process.env[APPLIED_ENV_FLAG];
};
exports.resetLoginShellPathForTests = resetLoginShellPathForTests;
//# sourceMappingURL=loginShellPath.js.mapSHA-256: 3089cbb1896ab33f3f5308bc3b6d6eab5d21d10a47f0dff27497f3ee8baaa2a2