mirror of
https://github.com/farcasclaudiu/openclaw.git
synced 2026-06-28 21:01:43 +03:00
refactor: dedupe PATH prepend helpers
This commit is contained in:
@@ -7,7 +7,9 @@ import type { ProcessSession, SessionStdin } from "./bash-process-registry.js";
|
|||||||
import type { ExecToolDetails } from "./bash-tools.exec.js";
|
import type { ExecToolDetails } from "./bash-tools.exec.js";
|
||||||
import type { BashSandboxConfig } from "./bash-tools.shared.js";
|
import type { BashSandboxConfig } from "./bash-tools.shared.js";
|
||||||
import { requestHeartbeatNow } from "../infra/heartbeat-wake.js";
|
import { requestHeartbeatNow } from "../infra/heartbeat-wake.js";
|
||||||
|
import { mergePathPrepend } from "../infra/path-prepend.js";
|
||||||
import { enqueueSystemEvent } from "../infra/system-events.js";
|
import { enqueueSystemEvent } from "../infra/system-events.js";
|
||||||
|
export { applyPathPrepend, normalizePathPrepend } from "../infra/path-prepend.js";
|
||||||
import { logWarn } from "../logger.js";
|
import { logWarn } from "../logger.js";
|
||||||
import { formatSpawnError, spawnWithFallback } from "../process/spawn-utils.js";
|
import { formatSpawnError, spawnWithFallback } from "../process/spawn-utils.js";
|
||||||
import {
|
import {
|
||||||
@@ -227,63 +229,6 @@ function compactNotifyOutput(value: string, maxChars = DEFAULT_NOTIFY_SNIPPET_CH
|
|||||||
return `${normalized.slice(0, safe)}…`;
|
return `${normalized.slice(0, safe)}…`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function normalizePathPrepend(entries?: string[]) {
|
|
||||||
if (!Array.isArray(entries)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
const seen = new Set<string>();
|
|
||||||
const normalized: string[] = [];
|
|
||||||
for (const entry of entries) {
|
|
||||||
if (typeof entry !== "string") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const trimmed = entry.trim();
|
|
||||||
if (!trimmed || seen.has(trimmed)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
seen.add(trimmed);
|
|
||||||
normalized.push(trimmed);
|
|
||||||
}
|
|
||||||
return normalized;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mergePathPrepend(existing: string | undefined, prepend: string[]) {
|
|
||||||
if (prepend.length === 0) {
|
|
||||||
return existing;
|
|
||||||
}
|
|
||||||
const partsExisting = (existing ?? "")
|
|
||||||
.split(path.delimiter)
|
|
||||||
.map((part) => part.trim())
|
|
||||||
.filter(Boolean);
|
|
||||||
const merged: string[] = [];
|
|
||||||
const seen = new Set<string>();
|
|
||||||
for (const part of [...prepend, ...partsExisting]) {
|
|
||||||
if (seen.has(part)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
seen.add(part);
|
|
||||||
merged.push(part);
|
|
||||||
}
|
|
||||||
return merged.join(path.delimiter);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function applyPathPrepend(
|
|
||||||
env: Record<string, string>,
|
|
||||||
prepend: string[],
|
|
||||||
options?: { requireExisting?: boolean },
|
|
||||||
) {
|
|
||||||
if (prepend.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (options?.requireExisting && !env.PATH) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const merged = mergePathPrepend(env.PATH, prepend);
|
|
||||||
if (merged) {
|
|
||||||
env.PATH = merged;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function applyShellPath(env: Record<string, string>, shellPath?: string | null) {
|
export function applyShellPath(env: Record<string, string>, shellPath?: string | null) {
|
||||||
if (!shellPath) {
|
if (!shellPath) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import type { Command } from "commander";
|
import type { Command } from "commander";
|
||||||
import path from "node:path";
|
|
||||||
import type { NodesRpcOpts } from "./types.js";
|
import type { NodesRpcOpts } from "./types.js";
|
||||||
import { resolveAgentConfig, resolveDefaultAgentId } from "../../agents/agent-scope.js";
|
import { resolveAgentConfig, resolveDefaultAgentId } from "../../agents/agent-scope.js";
|
||||||
import { loadConfig } from "../../config/config.js";
|
import { loadConfig } from "../../config/config.js";
|
||||||
@@ -14,6 +13,7 @@ import {
|
|||||||
resolveExecApprovalsFromFile,
|
resolveExecApprovalsFromFile,
|
||||||
} from "../../infra/exec-approvals.js";
|
} from "../../infra/exec-approvals.js";
|
||||||
import { buildNodeShellCommand } from "../../infra/node-shell.js";
|
import { buildNodeShellCommand } from "../../infra/node-shell.js";
|
||||||
|
import { applyPathPrepend } from "../../infra/path-prepend.js";
|
||||||
import { defaultRuntime } from "../../runtime.js";
|
import { defaultRuntime } from "../../runtime.js";
|
||||||
import { parseEnvPairs, parseTimeoutMs } from "../nodes-run.js";
|
import { parseEnvPairs, parseTimeoutMs } from "../nodes-run.js";
|
||||||
import { getNodesTheme, runNodesCommand } from "./cli-utils.js";
|
import { getNodesTheme, runNodesCommand } from "./cli-utils.js";
|
||||||
@@ -58,43 +58,6 @@ function normalizeExecAsk(value?: string | null): ExecAsk | null {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergePathPrepend(existing: string | undefined, prepend: string[]) {
|
|
||||||
if (prepend.length === 0) {
|
|
||||||
return existing;
|
|
||||||
}
|
|
||||||
const partsExisting = (existing ?? "")
|
|
||||||
.split(path.delimiter)
|
|
||||||
.map((part) => part.trim())
|
|
||||||
.filter(Boolean);
|
|
||||||
const merged: string[] = [];
|
|
||||||
const seen = new Set<string>();
|
|
||||||
for (const part of [...prepend, ...partsExisting]) {
|
|
||||||
if (seen.has(part)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
seen.add(part);
|
|
||||||
merged.push(part);
|
|
||||||
}
|
|
||||||
return merged.join(path.delimiter);
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyPathPrepend(
|
|
||||||
env: Record<string, string>,
|
|
||||||
prepend: string[] | undefined,
|
|
||||||
options?: { requireExisting?: boolean },
|
|
||||||
) {
|
|
||||||
if (!Array.isArray(prepend) || prepend.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (options?.requireExisting && !env.PATH) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const merged = mergePathPrepend(env.PATH, prepend);
|
|
||||||
if (merged) {
|
|
||||||
env.PATH = merged;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveExecDefaults(
|
function resolveExecDefaults(
|
||||||
cfg: ReturnType<typeof loadConfig>,
|
cfg: ReturnType<typeof loadConfig>,
|
||||||
agentId: string | undefined,
|
agentId: string | undefined,
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import path from "node:path";
|
||||||
|
|
||||||
|
export function normalizePathPrepend(entries?: string[]) {
|
||||||
|
if (!Array.isArray(entries)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const seen = new Set<string>();
|
||||||
|
const normalized: string[] = [];
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (typeof entry !== "string") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const trimmed = entry.trim();
|
||||||
|
if (!trimmed || seen.has(trimmed)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
seen.add(trimmed);
|
||||||
|
normalized.push(trimmed);
|
||||||
|
}
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mergePathPrepend(existing: string | undefined, prepend: string[]) {
|
||||||
|
if (prepend.length === 0) {
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
const partsExisting = (existing ?? "")
|
||||||
|
.split(path.delimiter)
|
||||||
|
.map((part) => part.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
const merged: string[] = [];
|
||||||
|
const seen = new Set<string>();
|
||||||
|
for (const part of [...prepend, ...partsExisting]) {
|
||||||
|
if (seen.has(part)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
seen.add(part);
|
||||||
|
merged.push(part);
|
||||||
|
}
|
||||||
|
return merged.join(path.delimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyPathPrepend(
|
||||||
|
env: Record<string, string>,
|
||||||
|
prepend: string[] | undefined,
|
||||||
|
options?: { requireExisting?: boolean },
|
||||||
|
) {
|
||||||
|
if (!Array.isArray(prepend) || prepend.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (options?.requireExisting && !env.PATH) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const merged = mergePathPrepend(env.PATH, prepend);
|
||||||
|
if (merged) {
|
||||||
|
env.PATH = merged;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user