Files
openclaw/src/node-host/node-worker-environment.ts
T
Peter Steinberger 438d035885 feat(gateway): launch workers on paired nodes (#123157)
* feat(gateway): launch workers on paired nodes

* docs(plan): track node worker launch wire

* fix(runners): restore node workspace ownership

Rehydrate durable workspace bindings after Gateway restart, fence timed-out node tunnel starts, and refuse incomplete clone fallback for submodule and Git LFS workspaces.

* test(runners): isolate node launch fixtures
2026-08-13 18:02:18 -07:00

56 lines
1.5 KiB
TypeScript

const POSIX_WORKER_ENV_KEYS = new Set([
"PATH",
"HOME",
"TMPDIR",
"TMP",
"TEMP",
"LANG",
"LANGUAGE",
"TZ",
"NODE_EXTRA_CA_CERTS",
"NODE_USE_SYSTEM_CA",
"OPENCLAW_ALLOW_INSECURE_PRIVATE_WS",
]);
const WINDOWS_WORKER_ENV_KEYS = new Set([
...POSIX_WORKER_ENV_KEYS,
"USERPROFILE",
"HOMEDRIVE",
"HOMEPATH",
"SYSTEMROOT",
"WINDIR",
"COMSPEC",
"PATHEXT",
]);
/** Freeze the minimal non-secret environment inherited by node-host workers. */
export function snapshotNodeWorkerEnv(source: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
const windows = process.platform === "win32";
const snapshot: NodeJS.ProcessEnv = {};
const retainedWindowsKeys = new Map<string, string>();
for (const [key, value] of Object.entries(source)) {
if (value === undefined) {
continue;
}
const normalized = windows ? key.toUpperCase() : key;
const allowed =
(windows ? WINDOWS_WORKER_ENV_KEYS : POSIX_WORKER_ENV_KEYS).has(normalized) ||
normalized.startsWith("LC_");
if (!allowed) {
continue;
}
if (windows) {
const previousKey = retainedWindowsKeys.get(normalized);
if (previousKey) {
delete snapshot[previousKey];
}
retainedWindowsKeys.set(normalized, key);
}
snapshot[key] = value;
}
// The supervised start gate is carried by Node IPC. Launcher respawns do not
// inherit that channel, so workers must stay in the owned child process.
snapshot.NODE_DISABLE_COMPILE_CACHE = "1";
snapshot.OPENCLAW_NO_RESPAWN = "1";
return snapshot;
}