"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.$ = buildAgentPeerSessionKey;exports.A = canUseBoundaryFileOpen;exports.B = isSymlinkOpenError;exports.C = filterBootstrapFilesForSession;exports.D = runCommandWithTimeout;exports.E = resolveOpenClawPackageRootSync;exports.F = resolveBoundaryPath;exports.G = normalizeStringEntries;exports.H = normalizeSkillFilter;exports.I = resolvePathViaExistingAncestorSync;exports.J = resolveAgentModelPrimaryValue;exports.K = normalizeStringEntriesLower;exports.L = hasNodeErrorCode;exports.M = openBoundaryFileSync;exports.N = sameFileIdentity$1;exports.O = runExec;exports.P = void 0;exports.Q = buildAgentMainSessionKey;exports.R = isNotFoundPathError;exports.S = ensureAgentWorkspace;exports.T = resolveOpenClawPackageRoot;exports.U = normalizeAtHashSlug;exports.V = normalizeWindowsPathForComparison;exports.W = normalizeHyphenSlug;exports.X = void 0;exports.Y = toAgentModelListLike;exports._ = exports.Z = void 0;exports._t = isSubagentSessionKey;exports.a = resolveAgentDir;exports.at = resolveAgentIdFromSessionKey;exports.b = void 0;exports.c = resolveAgentWorkspaceDir;exports.ct = scopedHeartbeatWakeOptions;exports.d = resolveRunModelFallbacksOverride;exports.dt = normalizeOptionalAccountId;exports.et = buildGroupHistoryKey;exports.f = resolveSessionAgentId;exports.ft = isBlockedObjectKey;exports.g = void 0;exports.gt = isCronSessionKey;exports.h = void 0;exports.ht = isAcpSessionKey;exports.i = resolveAgentConfig;exports.it = normalizeMainKey;exports.j = openBoundaryFile;exports.k = spawnWithFallback;exports.l = resolveDefaultAgentId;exports.m = exports.lt = void 0;exports.mt = getSubagentDepth;exports.n = hasConfiguredModelFallbacks;exports.nt = isValidAgentId;exports.o = resolveAgentEffectiveModelPrimary;exports.ot = resolveThreadSessionKeys;exports.p = resolveSessionAgentIds;exports.pt = deriveSessionChatType;exports.q = resolveAgentModelFallbackValues;exports.r = listAgentIds;exports.rt = normalizeAgentId;exports.s = resolveAgentSkillsFilter;exports.st = sanitizeAgentId;exports.t = runTasksWithConcurrency;exports.tt = classifySessionKeyShape;exports.u = resolveEffectiveModelFallbacks;exports.ut = normalizeAccountId;exports.v = void 0;exports.vt = parseAgentSessionKey;exports.w = loadWorkspaceBootstrapFiles;exports.y = exports.x = void 0;exports.yt = resolveThreadParentSessionKey;exports.z = isPathInside;var _pathsEFexkPEh = require("./paths-eFexkPEh.js"); var _loggerU3s76KST = require("./logger-U3s76KST.js"); var _nodeFs = _interopRequireDefault(require("node:fs")); var _nodePath = _interopRequireDefault(require("node:path")); var _nodeOs = _interopRequireDefault(require("node:os")); var _promises = _interopRequireDefault(require("node:fs/promises")); var _nodeUtil = require("node:util"); var _nodeChild_process = require("node:child_process"); var _nodeProcess = _interopRequireDefault(require("node:process")); var _nodeUrl = require("node:url");function _interopRequireDefault(e) {return e && e.__esModule ? e : { default: e };} //#region src/sessions/session-key-utils.ts /** * Parse agent-scoped session keys in a canonical, case-insensitive way. * Returned values are normalized to lowercase for stable comparisons/routing. */ function parseAgentSessionKey(sessionKey) { const raw = (sessionKey ?? "").trim().toLowerCase(); if (!raw) return null; const parts = raw.split(":").filter(Boolean); if (parts.length < 3) return null; if (parts[0] !== "agent") return null; const agentId = parts[1]?.trim(); const rest = parts.slice(2).join(":"); if (!agentId || !rest) return null; return { agentId, rest }; } /** * Best-effort chat-type extraction from session keys across canonical and legacy formats. */ function deriveSessionChatType(sessionKey) { const raw = (sessionKey ?? "").trim().toLowerCase(); if (!raw) return "unknown"; const scoped = parseAgentSessionKey(raw)?.rest ?? raw; const tokens = new Set(scoped.split(":").filter(Boolean)); if (tokens.has("group")) return "group"; if (tokens.has("channel")) return "channel"; if (tokens.has("direct") || tokens.has("dm")) return "direct"; if (/^discord:(?:[^:]+:)?guild-[^:]+:channel-[^:]+$/.test(scoped)) return "channel"; return "unknown"; } function isCronSessionKey(sessionKey) { const parsed = parseAgentSessionKey(sessionKey); if (!parsed) return false; return parsed.rest.toLowerCase().startsWith("cron:"); } function isSubagentSessionKey(sessionKey) { const raw = (sessionKey ?? "").trim(); if (!raw) return false; if (raw.toLowerCase().startsWith("subagent:")) return true; const parsed = parseAgentSessionKey(raw); return Boolean((parsed?.rest ?? "").toLowerCase().startsWith("subagent:")); } function getSubagentDepth(sessionKey) { const raw = (sessionKey ?? "").trim().toLowerCase(); if (!raw) return 0; return raw.split(":subagent:").length - 1; } function isAcpSessionKey(sessionKey) { const raw = (sessionKey ?? "").trim(); if (!raw) return false; if (raw.toLowerCase().startsWith("acp:")) return true; const parsed = parseAgentSessionKey(raw); return Boolean((parsed?.rest ?? "").toLowerCase().startsWith("acp:")); } const THREAD_SESSION_MARKERS = [":thread:", ":topic:"]; function resolveThreadParentSessionKey(sessionKey) { const raw = (sessionKey ?? "").trim(); if (!raw) return null; const normalized = raw.toLowerCase(); let idx = -1; for (const marker of THREAD_SESSION_MARKERS) { const candidate = normalized.lastIndexOf(marker); if (candidate > idx) idx = candidate; } if (idx <= 0) return null; const parent = raw.slice(0, idx).trim(); return parent ? parent : null; } //#endregion //#region src/infra/prototype-keys.ts const BLOCKED_OBJECT_KEYS = new Set([ "__proto__", "prototype", "constructor"] ); function isBlockedObjectKey(key) { return BLOCKED_OBJECT_KEYS.has(key); } //#endregion //#region src/routing/account-id.ts const DEFAULT_ACCOUNT_ID = exports.lt = "default"; const VALID_ID_RE$1 = /^[a-z0-9][a-z0-9_-]{0,63}$/i; const INVALID_CHARS_RE$1 = /[^a-z0-9_-]+/g; const LEADING_DASH_RE$1 = /^-+/; const TRAILING_DASH_RE$1 = /-+$/; const ACCOUNT_ID_CACHE_MAX = 512; const normalizeAccountIdCache = /* @__PURE__ */new Map(); const normalizeOptionalAccountIdCache = /* @__PURE__ */new Map(); function canonicalizeAccountId(value) { if (VALID_ID_RE$1.test(value)) return value.toLowerCase(); return value.toLowerCase().replace(INVALID_CHARS_RE$1, "-").replace(LEADING_DASH_RE$1, "").replace(TRAILING_DASH_RE$1, "").slice(0, 64); } function normalizeCanonicalAccountId(value) { const canonical = canonicalizeAccountId(value); if (!canonical || isBlockedObjectKey(canonical)) return; return canonical; } function normalizeAccountId(value) { const trimmed = (value ?? "").trim(); if (!trimmed) return DEFAULT_ACCOUNT_ID; const cached = normalizeAccountIdCache.get(trimmed); if (cached) return cached; const normalized = normalizeCanonicalAccountId(trimmed) || "default"; setNormalizeCache(normalizeAccountIdCache, trimmed, normalized); return normalized; } function normalizeOptionalAccountId(value) { const trimmed = (value ?? "").trim(); if (!trimmed) return; if (normalizeOptionalAccountIdCache.has(trimmed)) return normalizeOptionalAccountIdCache.get(trimmed); const normalized = normalizeCanonicalAccountId(trimmed) || void 0; setNormalizeCache(normalizeOptionalAccountIdCache, trimmed, normalized); return normalized; } function setNormalizeCache(cache, key, value) { cache.set(key, value); if (cache.size <= ACCOUNT_ID_CACHE_MAX) return; const oldest = cache.keys().next(); if (!oldest.done) cache.delete(oldest.value); } //#endregion //#region src/routing/session-key.ts const DEFAULT_AGENT_ID = exports.X = "main"; const DEFAULT_MAIN_KEY = exports.Z = "main"; const VALID_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i; const INVALID_CHARS_RE = /[^a-z0-9_-]+/g; const LEADING_DASH_RE = /^-+/; const TRAILING_DASH_RE = /-+$/; function normalizeToken(value) { return (value ?? "").trim().toLowerCase(); } function scopedHeartbeatWakeOptions(sessionKey, wakeOptions) { return parseAgentSessionKey(sessionKey) ? { ...wakeOptions, sessionKey } : wakeOptions; } function normalizeMainKey(value) { const trimmed = (value ?? "").trim(); return trimmed ? trimmed.toLowerCase() : DEFAULT_MAIN_KEY; } function resolveAgentIdFromSessionKey(sessionKey) { return normalizeAgentId(parseAgentSessionKey(sessionKey)?.agentId ?? "main"); } function classifySessionKeyShape(sessionKey) { const raw = (sessionKey ?? "").trim(); if (!raw) return "missing"; if (parseAgentSessionKey(raw)) return "agent"; return raw.toLowerCase().startsWith("agent:") ? "malformed_agent" : "legacy_or_alias"; } function normalizeAgentId(value) { const trimmed = (value ?? "").trim(); if (!trimmed) return DEFAULT_AGENT_ID; if (VALID_ID_RE.test(trimmed)) return trimmed.toLowerCase(); return trimmed.toLowerCase().replace(INVALID_CHARS_RE, "-").replace(LEADING_DASH_RE, "").replace(TRAILING_DASH_RE, "").slice(0, 64) || "main"; } function isValidAgentId(value) { const trimmed = (value ?? "").trim(); return Boolean(trimmed) && VALID_ID_RE.test(trimmed); } function sanitizeAgentId(value) { return normalizeAgentId(value); } function buildAgentMainSessionKey(params) { return `agent:${normalizeAgentId(params.agentId)}:${normalizeMainKey(params.mainKey)}`; } function buildAgentPeerSessionKey(params) { const peerKind = params.peerKind ?? "direct"; if (peerKind === "direct") { const dmScope = params.dmScope ?? "main"; let peerId = (params.peerId ?? "").trim(); const linkedPeerId = dmScope === "main" ? null : resolveLinkedPeerId({ identityLinks: params.identityLinks, channel: params.channel, peerId }); if (linkedPeerId) peerId = linkedPeerId; peerId = peerId.toLowerCase(); if (dmScope === "per-account-channel-peer" && peerId) { const channel = (params.channel ?? "").trim().toLowerCase() || "unknown"; const accountId = normalizeAccountId(params.accountId); return `agent:${normalizeAgentId(params.agentId)}:${channel}:${accountId}:direct:${peerId}`; } if (dmScope === "per-channel-peer" && peerId) { const channel = (params.channel ?? "").trim().toLowerCase() || "unknown"; return `agent:${normalizeAgentId(params.agentId)}:${channel}:direct:${peerId}`; } if (dmScope === "per-peer" && peerId) return `agent:${normalizeAgentId(params.agentId)}:direct:${peerId}`; return buildAgentMainSessionKey({ agentId: params.agentId, mainKey: params.mainKey }); } const channel = (params.channel ?? "").trim().toLowerCase() || "unknown"; const peerId = ((params.peerId ?? "").trim() || "unknown").toLowerCase(); return `agent:${normalizeAgentId(params.agentId)}:${channel}:${peerKind}:${peerId}`; } function resolveLinkedPeerId(params) { const identityLinks = params.identityLinks; if (!identityLinks) return null; const peerId = params.peerId.trim(); if (!peerId) return null; const candidates = /* @__PURE__ */new Set(); const rawCandidate = normalizeToken(peerId); if (rawCandidate) candidates.add(rawCandidate); const channel = normalizeToken(params.channel); if (channel) { const scopedCandidate = normalizeToken(`${channel}:${peerId}`); if (scopedCandidate) candidates.add(scopedCandidate); } if (candidates.size === 0) return null; for (const [canonical, ids] of Object.entries(identityLinks)) { const canonicalName = canonical.trim(); if (!canonicalName) continue; if (!Array.isArray(ids)) continue; for (const id of ids) { const normalized = normalizeToken(id); if (normalized && candidates.has(normalized)) return canonicalName; } } return null; } function buildGroupHistoryKey(params) { const channel = normalizeToken(params.channel) || "unknown"; const accountId = normalizeAccountId(params.accountId); const peerId = params.peerId.trim().toLowerCase() || "unknown"; return `${channel}:${accountId}:${params.peerKind}:${peerId}`; } function resolveThreadSessionKeys(params) { const threadId = (params.threadId ?? "").trim(); if (!threadId) return { sessionKey: params.baseSessionKey, parentSessionKey: void 0 }; const normalizedThreadId = (params.normalizeThreadId ?? ((value) => value.toLowerCase()))(threadId); return { sessionKey: params.useSuffix ?? true ? `${params.baseSessionKey}:thread:${normalizedThreadId}` : params.baseSessionKey, parentSessionKey: params.parentSessionKey }; } //#endregion //#region src/config/model-input.ts function resolveAgentModelPrimaryValue(model) { if (typeof model === "string") return model.trim() || void 0; if (!model || typeof model !== "object") return; return model.primary?.trim() || void 0; } function resolveAgentModelFallbackValues(model) { if (!model || typeof model !== "object") return []; return Array.isArray(model.fallbacks) ? model.fallbacks : []; } function toAgentModelListLike(model) { if (typeof model === "string") { const primary = model.trim(); return primary ? { primary } : void 0; } if (!model || typeof model !== "object") return; return model; } //#endregion //#region src/shared/string-normalization.ts function normalizeStringEntries(list) { return (list ?? []).map((entry) => String(entry).trim()).filter(Boolean); } function normalizeStringEntriesLower(list) { return normalizeStringEntries(list).map((entry) => entry.toLowerCase()); } function normalizeHyphenSlug(raw) { const trimmed = raw?.trim().toLowerCase() ?? ""; if (!trimmed) return ""; return trimmed.replace(/\s+/g, "-").replace(/[^a-z0-9#@._+-]+/g, "-").replace(/-{2,}/g, "-").replace(/^[-.]+|[-.]+$/g, ""); } function normalizeAtHashSlug(raw) { const trimmed = raw?.trim().toLowerCase() ?? ""; if (!trimmed) return ""; return trimmed.replace(/^[@#]+/, "").replace(/[\s_]+/g, "-").replace(/[^a-z0-9-]+/g, "-").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, ""); } //#endregion //#region src/agents/skills/filter.ts function normalizeSkillFilter(skillFilter) { if (skillFilter === void 0) return; return normalizeStringEntries(skillFilter); } //#endregion //#region src/infra/path-guards.ts const NOT_FOUND_CODES = new Set(["ENOENT", "ENOTDIR"]); const SYMLINK_OPEN_CODES = new Set([ "ELOOP", "EINVAL", "ENOTSUP"] ); function normalizeWindowsPathForComparison(input) { let normalized = _nodePath.default.win32.normalize(input); if (normalized.startsWith("\\\\?\\")) { normalized = normalized.slice(4); if (normalized.toUpperCase().startsWith("UNC\\")) normalized = `\\\\${normalized.slice(4)}`; } return normalized.replaceAll("/", "\\").toLowerCase(); } function isNodeError(value) { return Boolean(value && typeof value === "object" && "code" in value); } function hasNodeErrorCode(value, code) { return isNodeError(value) && value.code === code; } function isNotFoundPathError(value) { return isNodeError(value) && typeof value.code === "string" && NOT_FOUND_CODES.has(value.code); } function isSymlinkOpenError(value) { return isNodeError(value) && typeof value.code === "string" && SYMLINK_OPEN_CODES.has(value.code); } function isPathInside(root, target) { const resolvedRoot = _nodePath.default.resolve(root); const resolvedTarget = _nodePath.default.resolve(target); if (process.platform === "win32") { const rootForCompare = normalizeWindowsPathForComparison(resolvedRoot); const targetForCompare = normalizeWindowsPathForComparison(resolvedTarget); const relative = _nodePath.default.win32.relative(rootForCompare, targetForCompare); return relative === "" || !relative.startsWith("..") && !_nodePath.default.win32.isAbsolute(relative); } const relative = _nodePath.default.relative(resolvedRoot, resolvedTarget); return relative === "" || !relative.startsWith("..") && !_nodePath.default.isAbsolute(relative); } //#endregion //#region src/infra/boundary-path.ts const BOUNDARY_PATH_ALIAS_POLICIES = exports.P = { strict: Object.freeze({ allowFinalSymlinkForUnlink: false, allowFinalHardlinkForUnlink: false }), unlinkTarget: Object.freeze({ allowFinalSymlinkForUnlink: true, allowFinalHardlinkForUnlink: true }) }; async function resolveBoundaryPath(params) { const rootPath = _nodePath.default.resolve(params.rootPath); const absolutePath = _nodePath.default.resolve(params.absolutePath); const context = createBoundaryResolutionContext({ resolveParams: params, rootPath, absolutePath, rootCanonicalPath: params.rootCanonicalPath ? _nodePath.default.resolve(params.rootCanonicalPath) : await resolvePathViaExistingAncestor(rootPath), outsideLexicalCanonicalPath: await resolveOutsideLexicalCanonicalPathAsync({ rootPath, absolutePath }) }); const outsideResult = await resolveOutsideBoundaryPathAsync({ boundaryLabel: params.boundaryLabel, context }); if (outsideResult) return outsideResult; return resolveBoundaryPathLexicalAsync({ params, absolutePath: context.absolutePath, rootPath: context.rootPath, rootCanonicalPath: context.rootCanonicalPath }); } function resolveBoundaryPathSync(params) { const rootPath = _nodePath.default.resolve(params.rootPath); const absolutePath = _nodePath.default.resolve(params.absolutePath); const context = createBoundaryResolutionContext({ resolveParams: params, rootPath, absolutePath, rootCanonicalPath: params.rootCanonicalPath ? _nodePath.default.resolve(params.rootCanonicalPath) : resolvePathViaExistingAncestorSync(rootPath), outsideLexicalCanonicalPath: resolveOutsideLexicalCanonicalPathSync({ rootPath, absolutePath }) }); const outsideResult = resolveOutsideBoundaryPathSync({ boundaryLabel: params.boundaryLabel, context }); if (outsideResult) return outsideResult; return resolveBoundaryPathLexicalSync({ params, absolutePath: context.absolutePath, rootPath: context.rootPath, rootCanonicalPath: context.rootCanonicalPath }); } function isPromiseLike(value) { return Boolean(value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function"); } function createLexicalTraversalState(params) { return { segments: _nodePath.default.relative(params.rootPath, params.absolutePath).split(_nodePath.default.sep).filter(Boolean), allowFinalSymlink: params.params.policy?.allowFinalSymlinkForUnlink === true, canonicalCursor: params.rootCanonicalPath, lexicalCursor: params.rootPath, preserveFinalSymlink: false }; } function assertLexicalCursorInsideBoundary(params) { assertInsideBoundary({ boundaryLabel: params.params.boundaryLabel, rootCanonicalPath: params.rootCanonicalPath, candidatePath: params.candidatePath, absolutePath: params.absolutePath }); } function applyMissingSuffixToCanonicalCursor(params) { const missingSuffix = params.state.segments.slice(params.missingFromIndex); params.state.canonicalCursor = _nodePath.default.resolve(params.state.canonicalCursor, ...missingSuffix); assertLexicalCursorInsideBoundary({ params: params.params, rootCanonicalPath: params.rootCanonicalPath, candidatePath: params.state.canonicalCursor, absolutePath: params.absolutePath }); } function advanceCanonicalCursorForSegment(params) { params.state.canonicalCursor = _nodePath.default.resolve(params.state.canonicalCursor, params.segment); assertLexicalCursorInsideBoundary({ params: params.params, rootCanonicalPath: params.rootCanonicalPath, candidatePath: params.state.canonicalCursor, absolutePath: params.absolutePath }); } function finalizeLexicalResolution(params) { assertLexicalCursorInsideBoundary({ params: params.params, rootCanonicalPath: params.rootCanonicalPath, candidatePath: params.state.canonicalCursor, absolutePath: params.absolutePath }); return buildResolvedBoundaryPath({ absolutePath: params.absolutePath, canonicalPath: params.state.canonicalCursor, rootPath: params.rootPath, rootCanonicalPath: params.rootCanonicalPath, kind: params.kind }); } function handleLexicalLstatFailure(params) { if (!isNotFoundPathError(params.error)) return false; applyMissingSuffixToCanonicalCursor({ state: params.state, missingFromIndex: params.missingFromIndex, rootCanonicalPath: params.rootCanonicalPath, params: params.resolveParams, absolutePath: params.absolutePath }); return true; } function handleLexicalStatReadFailure(params) { if (handleLexicalLstatFailure({ error: params.error, state: params.state, missingFromIndex: params.missingFromIndex, rootCanonicalPath: params.rootCanonicalPath, resolveParams: params.resolveParams, absolutePath: params.absolutePath })) return null; throw params.error; } function handleLexicalStatDisposition(params) { if (!params.isSymbolicLink) { advanceCanonicalCursorForSegment({ state: params.state, segment: params.segment, rootCanonicalPath: params.rootCanonicalPath, params: params.resolveParams, absolutePath: params.absolutePath }); return "continue"; } if (params.state.allowFinalSymlink && params.isLast) { params.state.preserveFinalSymlink = true; advanceCanonicalCursorForSegment({ state: params.state, segment: params.segment, rootCanonicalPath: params.rootCanonicalPath, params: params.resolveParams, absolutePath: params.absolutePath }); return "break"; } return "resolve-link"; } function applyResolvedSymlinkHop(params) { if (!isPathInside(params.rootCanonicalPath, params.linkCanonical)) throw symlinkEscapeError({ boundaryLabel: params.boundaryLabel, rootCanonicalPath: params.rootCanonicalPath, symlinkPath: params.state.lexicalCursor }); params.state.canonicalCursor = params.linkCanonical; params.state.lexicalCursor = params.linkCanonical; } function readLexicalStat(params) { try { const stat = params.read(params.state.lexicalCursor); if (isPromiseLike(stat)) return Promise.resolve(stat).catch((error) => handleLexicalStatReadFailure({ ...params, error })); return stat; } catch (error) { return handleLexicalStatReadFailure({ ...params, error }); } } function resolveAndApplySymlinkHop(params) { const linkCanonical = params.resolveLinkCanonical(params.state.lexicalCursor); if (isPromiseLike(linkCanonical)) return Promise.resolve(linkCanonical).then((value) => applyResolvedSymlinkHop({ state: params.state, linkCanonical: value, rootCanonicalPath: params.rootCanonicalPath, boundaryLabel: params.boundaryLabel })); applyResolvedSymlinkHop({ state: params.state, linkCanonical, rootCanonicalPath: params.rootCanonicalPath, boundaryLabel: params.boundaryLabel }); } function* iterateLexicalTraversal(state) { for (let idx = 0; idx < state.segments.length; idx += 1) { const segment = state.segments[idx] ?? ""; const isLast = idx === state.segments.length - 1; state.lexicalCursor = _nodePath.default.join(state.lexicalCursor, segment); yield { idx, segment, isLast }; } } async function resolveBoundaryPathLexicalAsync(params) { const state = createLexicalTraversalState(params); const sharedStepParams = { state, rootCanonicalPath: params.rootCanonicalPath, resolveParams: params.params, absolutePath: params.absolutePath }; for (const { idx, segment, isLast } of iterateLexicalTraversal(state)) { const stat = await readLexicalStat({ ...sharedStepParams, missingFromIndex: idx, read: (cursor) => _promises.default.lstat(cursor) }); if (!stat) break; const disposition = handleLexicalStatDisposition({ ...sharedStepParams, isSymbolicLink: stat.isSymbolicLink(), segment, isLast }); if (disposition === "continue") continue; if (disposition === "break") break; await resolveAndApplySymlinkHop({ state, rootCanonicalPath: params.rootCanonicalPath, boundaryLabel: params.params.boundaryLabel, resolveLinkCanonical: (cursor) => resolveSymlinkHopPath(cursor) }); } const kind = await getPathKind(params.absolutePath, state.preserveFinalSymlink); return finalizeLexicalResolution({ ...params, state, kind }); } function resolveBoundaryPathLexicalSync(params) { const state = createLexicalTraversalState(params); for (let idx = 0; idx < state.segments.length; idx += 1) { const segment = state.segments[idx] ?? ""; const isLast = idx === state.segments.length - 1; state.lexicalCursor = _nodePath.default.join(state.lexicalCursor, segment); const maybeStat = readLexicalStat({ state, missingFromIndex: idx, rootCanonicalPath: params.rootCanonicalPath, resolveParams: params.params, absolutePath: params.absolutePath, read: (cursor) => _nodeFs.default.lstatSync(cursor) }); if (isPromiseLike(maybeStat)) throw new Error("Unexpected async lexical stat"); const stat = maybeStat; if (!stat) break; const disposition = handleLexicalStatDisposition({ state, isSymbolicLink: stat.isSymbolicLink(), segment, isLast, rootCanonicalPath: params.rootCanonicalPath, resolveParams: params.params, absolutePath: params.absolutePath }); if (disposition === "continue") continue; if (disposition === "break") break; if (isPromiseLike(resolveAndApplySymlinkHop({ state, rootCanonicalPath: params.rootCanonicalPath, boundaryLabel: params.params.boundaryLabel, resolveLinkCanonical: (cursor) => resolveSymlinkHopPathSync(cursor) }))) throw new Error("Unexpected async symlink resolution"); } const kind = getPathKindSync(params.absolutePath, state.preserveFinalSymlink); return finalizeLexicalResolution({ ...params, state, kind }); } function resolveCanonicalOutsideLexicalPath(params) { return params.outsideLexicalCanonicalPath ?? params.absolutePath; } function createBoundaryResolutionContext(params) { const lexicalInside = isPathInside(params.rootPath, params.absolutePath); const canonicalOutsideLexicalPath = resolveCanonicalOutsideLexicalPath({ absolutePath: params.absolutePath, outsideLexicalCanonicalPath: params.outsideLexicalCanonicalPath }); assertLexicalBoundaryOrCanonicalAlias({ skipLexicalRootCheck: params.resolveParams.skipLexicalRootCheck, lexicalInside, canonicalOutsideLexicalPath, rootCanonicalPath: params.rootCanonicalPath, boundaryLabel: params.resolveParams.boundaryLabel, rootPath: params.rootPath, absolutePath: params.absolutePath }); return { rootPath: params.rootPath, absolutePath: params.absolutePath, rootCanonicalPath: params.rootCanonicalPath, lexicalInside, canonicalOutsideLexicalPath }; } async function resolveOutsideBoundaryPathAsync(params) { if (params.context.lexicalInside) return null; const kind = await getPathKind(params.context.absolutePath, false); return buildOutsideBoundaryPathFromContext({ boundaryLabel: params.boundaryLabel, context: params.context, kind }); } function resolveOutsideBoundaryPathSync(params) { if (params.context.lexicalInside) return null; const kind = getPathKindSync(params.context.absolutePath, false); return buildOutsideBoundaryPathFromContext({ boundaryLabel: params.boundaryLabel, context: params.context, kind }); } function buildOutsideBoundaryPathFromContext(params) { return buildOutsideLexicalBoundaryPath({ boundaryLabel: params.boundaryLabel, rootCanonicalPath: params.context.rootCanonicalPath, absolutePath: params.context.absolutePath, canonicalOutsideLexicalPath: params.context.canonicalOutsideLexicalPath, rootPath: params.context.rootPath, kind: params.kind }); } async function resolveOutsideLexicalCanonicalPathAsync(params) { if (isPathInside(params.rootPath, params.absolutePath)) return; return await resolvePathViaExistingAncestor(params.absolutePath); } function resolveOutsideLexicalCanonicalPathSync(params) { if (isPathInside(params.rootPath, params.absolutePath)) return; return resolvePathViaExistingAncestorSync(params.absolutePath); } function buildOutsideLexicalBoundaryPath(params) { assertInsideBoundary({ boundaryLabel: params.boundaryLabel, rootCanonicalPath: params.rootCanonicalPath, candidatePath: params.canonicalOutsideLexicalPath, absolutePath: params.absolutePath }); return buildResolvedBoundaryPath({ absolutePath: params.absolutePath, canonicalPath: params.canonicalOutsideLexicalPath, rootPath: params.rootPath, rootCanonicalPath: params.rootCanonicalPath, kind: params.kind }); } function assertLexicalBoundaryOrCanonicalAlias(params) { if (params.skipLexicalRootCheck || params.lexicalInside) return; if (isPathInside(params.rootCanonicalPath, params.canonicalOutsideLexicalPath)) return; throw pathEscapeError({ boundaryLabel: params.boundaryLabel, rootPath: params.rootPath, absolutePath: params.absolutePath }); } function buildResolvedBoundaryPath(params) { return { absolutePath: params.absolutePath, canonicalPath: params.canonicalPath, rootPath: params.rootPath, rootCanonicalPath: params.rootCanonicalPath, relativePath: relativeInsideRoot(params.rootCanonicalPath, params.canonicalPath), exists: params.kind.exists, kind: params.kind.kind }; } async function resolvePathViaExistingAncestor(targetPath) { const normalized = _nodePath.default.resolve(targetPath); let cursor = normalized; const missingSuffix = []; while (!isFilesystemRoot(cursor) && !(await pathExists(cursor))) { missingSuffix.unshift(_nodePath.default.basename(cursor)); const parent = _nodePath.default.dirname(cursor); if (parent === cursor) break; cursor = parent; } if (!(await pathExists(cursor))) return normalized; try { const resolvedAncestor = _nodePath.default.resolve(await _promises.default.realpath(cursor)); if (missingSuffix.length === 0) return resolvedAncestor; return _nodePath.default.resolve(resolvedAncestor, ...missingSuffix); } catch { return normalized; } } function resolvePathViaExistingAncestorSync(targetPath) { const normalized = _nodePath.default.resolve(targetPath); let cursor = normalized; const missingSuffix = []; while (!isFilesystemRoot(cursor) && !_nodeFs.default.existsSync(cursor)) { missingSuffix.unshift(_nodePath.default.basename(cursor)); const parent = _nodePath.default.dirname(cursor); if (parent === cursor) break; cursor = parent; } if (!_nodeFs.default.existsSync(cursor)) return normalized; try { const resolvedAncestor = _nodePath.default.resolve(_nodeFs.default.realpathSync(cursor)); if (missingSuffix.length === 0) return resolvedAncestor; return _nodePath.default.resolve(resolvedAncestor, ...missingSuffix); } catch { return normalized; } } async function getPathKind(absolutePath, preserveFinalSymlink) { try { return { exists: true, kind: toResolvedKind(preserveFinalSymlink ? await _promises.default.lstat(absolutePath) : await _promises.default.stat(absolutePath)) }; } catch (error) { if (isNotFoundPathError(error)) return { exists: false, kind: "missing" }; throw error; } } function getPathKindSync(absolutePath, preserveFinalSymlink) { try { return { exists: true, kind: toResolvedKind(preserveFinalSymlink ? _nodeFs.default.lstatSync(absolutePath) : _nodeFs.default.statSync(absolutePath)) }; } catch (error) { if (isNotFoundPathError(error)) return { exists: false, kind: "missing" }; throw error; } } function toResolvedKind(stat) { if (stat.isFile()) return "file"; if (stat.isDirectory()) return "directory"; if (stat.isSymbolicLink()) return "symlink"; return "other"; } function relativeInsideRoot(rootPath, targetPath) { const relative = _nodePath.default.relative(_nodePath.default.resolve(rootPath), _nodePath.default.resolve(targetPath)); if (!relative || relative === ".") return ""; if (relative.startsWith("..") || _nodePath.default.isAbsolute(relative)) return ""; return relative; } function assertInsideBoundary(params) { if (isPathInside(params.rootCanonicalPath, params.candidatePath)) return; throw new Error(`Path resolves outside ${params.boundaryLabel} (${shortPath(params.rootCanonicalPath)}): ${shortPath(params.absolutePath)}`); } function pathEscapeError(params) { return /* @__PURE__ */new Error(`Path escapes ${params.boundaryLabel} (${shortPath(params.rootPath)}): ${shortPath(params.absolutePath)}`); } function symlinkEscapeError(params) { return /* @__PURE__ */new Error(`Symlink escapes ${params.boundaryLabel} (${shortPath(params.rootCanonicalPath)}): ${shortPath(params.symlinkPath)}`); } function shortPath(value) { const home = _nodeOs.default.homedir(); if (value.startsWith(home)) return `~${value.slice(home.length)}`; return value; } function isFilesystemRoot(candidate) { return _nodePath.default.parse(candidate).root === candidate; } async function pathExists(targetPath) { try { await _promises.default.lstat(targetPath); return true; } catch (error) { if (isNotFoundPathError(error)) return false; throw error; } } async function resolveSymlinkHopPath(symlinkPath) { try { return _nodePath.default.resolve(await _promises.default.realpath(symlinkPath)); } catch (error) { if (!isNotFoundPathError(error)) throw error; const linkTarget = await _promises.default.readlink(symlinkPath); return resolvePathViaExistingAncestor(_nodePath.default.resolve(_nodePath.default.dirname(symlinkPath), linkTarget)); } } function resolveSymlinkHopPathSync(symlinkPath) { try { return _nodePath.default.resolve(_nodeFs.default.realpathSync(symlinkPath)); } catch (error) { if (!isNotFoundPathError(error)) throw error; const linkTarget = _nodeFs.default.readlinkSync(symlinkPath); return resolvePathViaExistingAncestorSync(_nodePath.default.resolve(_nodePath.default.dirname(symlinkPath), linkTarget)); } } //#endregion //#region src/infra/file-identity.ts function isZero(value) { return value === 0 || value === 0n; } function sameFileIdentity$1(left, right, platform = process.platform) { if (left.ino !== right.ino) return false; if (left.dev === right.dev) return true; return platform === "win32" && (isZero(left.dev) || isZero(right.dev)); } //#endregion //#region src/infra/safe-open-sync.ts function isExpectedPathError(error) { const code = typeof error === "object" && error !== null && "code" in error ? String(error.code) : ""; return code === "ENOENT" || code === "ENOTDIR" || code === "ELOOP"; } function sameFileIdentity(left, right) { return sameFileIdentity$1(left, right); } function openVerifiedFileSync(params) { const ioFs = params.ioFs ?? _nodeFs.default; const allowedType = params.allowedType ?? "file"; const openReadFlags = ioFs.constants.O_RDONLY | (typeof ioFs.constants.O_NOFOLLOW === "number" ? ioFs.constants.O_NOFOLLOW : 0); let fd = null; try { if (params.rejectPathSymlink) { if (ioFs.lstatSync(params.filePath).isSymbolicLink()) return { ok: false, reason: "validation" }; } const realPath = params.resolvedPath ?? ioFs.realpathSync(params.filePath); const preOpenStat = ioFs.lstatSync(realPath); if (!isAllowedType(preOpenStat, allowedType)) return { ok: false, reason: "validation" }; if (params.rejectHardlinks && preOpenStat.isFile() && preOpenStat.nlink > 1) return { ok: false, reason: "validation" }; if (params.maxBytes !== void 0 && preOpenStat.isFile() && preOpenStat.size > params.maxBytes) return { ok: false, reason: "validation" }; fd = ioFs.openSync(realPath, openReadFlags); const openedStat = ioFs.fstatSync(fd); if (!isAllowedType(openedStat, allowedType)) return { ok: false, reason: "validation" }; if (params.rejectHardlinks && openedStat.isFile() && openedStat.nlink > 1) return { ok: false, reason: "validation" }; if (params.maxBytes !== void 0 && openedStat.isFile() && openedStat.size > params.maxBytes) return { ok: false, reason: "validation" }; if (!sameFileIdentity(preOpenStat, openedStat)) return { ok: false, reason: "validation" }; const opened = { ok: true, path: realPath, fd, stat: openedStat }; fd = null; return opened; } catch (error) { if (isExpectedPathError(error)) return { ok: false, reason: "path", error }; return { ok: false, reason: "io", error }; } finally { if (fd !== null) ioFs.closeSync(fd); } } function isAllowedType(stat, allowedType) { if (allowedType === "directory") return stat.isDirectory(); return stat.isFile(); } //#endregion //#region src/infra/boundary-file-read.ts function canUseBoundaryFileOpen(ioFs) { return typeof ioFs.openSync === "function" && typeof ioFs.closeSync === "function" && typeof ioFs.fstatSync === "function" && typeof ioFs.lstatSync === "function" && typeof ioFs.realpathSync === "function" && typeof ioFs.readFileSync === "function" && typeof ioFs.constants === "object" && ioFs.constants !== null; } function openBoundaryFileSync(params) { const ioFs = params.ioFs ?? _nodeFs.default; const resolved = resolveBoundaryFilePathGeneric({ absolutePath: params.absolutePath, resolve: (absolutePath) => resolveBoundaryPathSync({ absolutePath, rootPath: params.rootPath, rootCanonicalPath: params.rootRealPath, boundaryLabel: params.boundaryLabel, skipLexicalRootCheck: params.skipLexicalRootCheck }) }); if (resolved instanceof Promise) return toBoundaryValidationError(/* @__PURE__ */new Error("Unexpected async boundary resolution")); return finalizeBoundaryFileOpen({ resolved, maxBytes: params.maxBytes, rejectHardlinks: params.rejectHardlinks, allowedType: params.allowedType, ioFs }); } function openBoundaryFileResolved(params) { const opened = openVerifiedFileSync({ filePath: params.absolutePath, resolvedPath: params.resolvedPath, rejectHardlinks: params.rejectHardlinks ?? true, maxBytes: params.maxBytes, allowedType: params.allowedType, ioFs: params.ioFs }); if (!opened.ok) return opened; return { ok: true, path: opened.path, fd: opened.fd, stat: opened.stat, rootRealPath: params.rootRealPath }; } function finalizeBoundaryFileOpen(params) { if ("ok" in params.resolved) return params.resolved; return openBoundaryFileResolved({ absolutePath: params.resolved.absolutePath, resolvedPath: params.resolved.resolvedPath, rootRealPath: params.resolved.rootRealPath, maxBytes: params.maxBytes, rejectHardlinks: params.rejectHardlinks, allowedType: params.allowedType, ioFs: params.ioFs }); } async function openBoundaryFile(params) { const ioFs = params.ioFs ?? _nodeFs.default; const maybeResolved = resolveBoundaryFilePathGeneric({ absolutePath: params.absolutePath, resolve: (absolutePath) => resolveBoundaryPath({ absolutePath, rootPath: params.rootPath, rootCanonicalPath: params.rootRealPath, boundaryLabel: params.boundaryLabel, policy: params.aliasPolicy, skipLexicalRootCheck: params.skipLexicalRootCheck }) }); return finalizeBoundaryFileOpen({ resolved: maybeResolved instanceof Promise ? await maybeResolved : maybeResolved, maxBytes: params.maxBytes, rejectHardlinks: params.rejectHardlinks, allowedType: params.allowedType, ioFs }); } function toBoundaryValidationError(error) { return { ok: false, reason: "validation", error }; } function mapResolvedBoundaryPath(absolutePath, resolved) { return { absolutePath, resolvedPath: resolved.canonicalPath, rootRealPath: resolved.rootCanonicalPath }; } function resolveBoundaryFilePathGeneric(params) { const absolutePath = _nodePath.default.resolve(params.absolutePath); try { const resolved = params.resolve(absolutePath); if (resolved instanceof Promise) return resolved.then((value) => mapResolvedBoundaryPath(absolutePath, value)).catch((error) => toBoundaryValidationError(error)); return mapResolvedBoundaryPath(absolutePath, resolved); } catch (error) { return toBoundaryValidationError(error); } } //#endregion //#region src/process/spawn-utils.ts const DEFAULT_RETRY_CODES = ["EBADF"]; function resolveCommandStdio(params) { return [ params.hasInput ? "pipe" : params.preferInherit ? "inherit" : "pipe", "pipe", "pipe"]; } function shouldRetry(err, codes) { const code = err && typeof err === "object" && "code" in err ? String(err.code) : ""; return code.length > 0 && codes.includes(code); } async function spawnAndWaitForSpawn(spawnImpl, argv, options) { const child = spawnImpl(argv[0], argv.slice(1), options); return await new Promise((resolve, reject) => { let settled = false; const cleanup = () => { child.removeListener("error", onError); child.removeListener("spawn", onSpawn); }; const finishResolve = () => { if (settled) return; settled = true; cleanup(); resolve(child); }; const onError = (err) => { if (settled) return; settled = true; cleanup(); reject(err); }; const onSpawn = () => { finishResolve(); }; child.once("error", onError); child.once("spawn", onSpawn); process.nextTick(() => { if (typeof child.pid === "number") finishResolve(); }); }); } async function spawnWithFallback(params) { const spawnImpl = params.spawnImpl ?? _nodeChild_process.spawn; const retryCodes = params.retryCodes ?? DEFAULT_RETRY_CODES; const baseOptions = { ...params.options }; const fallbacks = params.fallbacks ?? []; const attempts = [{ options: baseOptions }, ...fallbacks.map((fallback) => ({ label: fallback.label, options: { ...baseOptions, ...fallback.options } }))]; let lastError; for (let index = 0; index < attempts.length; index += 1) { const attempt = attempts[index]; try { return { child: await spawnAndWaitForSpawn(spawnImpl, params.argv, attempt.options), usedFallback: index > 0, fallbackLabel: attempt.label }; } catch (err) { lastError = err; const nextFallback = fallbacks[index]; if (!nextFallback || !shouldRetry(err, retryCodes)) throw err; params.onFallback?.(err, nextFallback); } } throw lastError; } //#endregion //#region src/process/exec.ts const execFileAsync = (0, _nodeUtil.promisify)(_nodeChild_process.execFile); const WINDOWS_UNSAFE_CMD_CHARS_RE = /[&|<>^%\r\n]/; function isWindowsBatchCommand(resolvedCommand) { if (_nodeProcess.default.platform !== "win32") return false; const ext = _nodePath.default.extname(resolvedCommand).toLowerCase(); return ext === ".cmd" || ext === ".bat"; } function escapeForCmdExe(arg) { if (WINDOWS_UNSAFE_CMD_CHARS_RE.test(arg)) throw new Error(`Unsafe Windows cmd.exe argument detected: ${JSON.stringify(arg)}. Pass an explicit shell-wrapper argv at the call site instead.`); if (!arg.includes(" ") && !arg.includes("\"")) return arg; return `"${arg.replace(/"/g, "\"\"")}"`; } function buildCmdExeCommandLine(resolvedCommand, args) { return [escapeForCmdExe(resolvedCommand), ...args.map(escapeForCmdExe)].join(" "); } /** * On Windows, Node 18.20.2+ (CVE-2024-27980) rejects spawning .cmd/.bat directly * without shell, causing EINVAL. Resolve npm/npx to node + cli script so we * spawn node.exe instead of npm.cmd. */ function resolveNpmArgvForWindows(argv) { if (_nodeProcess.default.platform !== "win32" || argv.length === 0) return null; const basename = _nodePath.default.basename(argv[0]).toLowerCase().replace(/\.(cmd|exe|bat)$/, ""); const cliName = basename === "npx" ? "npx-cli.js" : basename === "npm" ? "npm-cli.js" : null; if (!cliName) return null; const nodeDir = _nodePath.default.dirname(_nodeProcess.default.execPath); const cliPath = _nodePath.default.join(nodeDir, "node_modules", "npm", "bin", cliName); if (!_nodeFs.default.existsSync(cliPath)) { const command = argv[0] ?? ""; return [_nodePath.default.extname(command).toLowerCase() ? command : `${command}.cmd`, ...argv.slice(1)]; } return [ _nodeProcess.default.execPath, cliPath, ...argv.slice(1)]; } /** * Resolves a command for Windows compatibility. * On Windows, non-.exe commands (like pnpm, yarn) are resolved to .cmd; npm/npx * are handled by resolveNpmArgvForWindows to avoid spawn EINVAL (no direct .cmd). */ function resolveCommand(command) { if (_nodeProcess.default.platform !== "win32") return command; const basename = _nodePath.default.basename(command).toLowerCase(); if (_nodePath.default.extname(basename)) return command; if (["pnpm", "yarn"].includes(basename)) return `${command}.cmd`; return command; } function shouldSpawnWithShell(params) { return false; } async function runExec(command, args, opts = 1e4) { const options = typeof opts === "number" ? { timeout: opts, encoding: "utf8" } : { timeout: opts.timeoutMs, maxBuffer: opts.maxBuffer, cwd: opts.cwd, encoding: "utf8" }; try { const argv = [command, ...args]; let execCommand; let execArgs; if (_nodeProcess.default.platform === "win32") { const resolved = resolveNpmArgvForWindows(argv); if (resolved) { execCommand = resolved[0] ?? ""; execArgs = resolved.slice(1); } else { execCommand = resolveCommand(command); execArgs = args; } } else { execCommand = resolveCommand(command); execArgs = args; } const { stdout, stderr } = isWindowsBatchCommand(execCommand) ? await execFileAsync(_nodeProcess.default.env.ComSpec ?? "cmd.exe", [ "/d", "/s", "/c", buildCmdExeCommandLine(execCommand, execArgs)], { ...options, windowsVerbatimArguments: true }) : await execFileAsync(execCommand, execArgs, options); if ((0, _loggerU3s76KST.B)()) { if (stdout.trim()) (0, _loggerU3s76KST.t)(stdout.trim()); if (stderr.trim()) (0, _loggerU3s76KST.n)(stderr.trim()); } return { stdout, stderr }; } catch (err) { if ((0, _loggerU3s76KST.B)()) (0, _loggerU3s76KST.n)((0, _loggerU3s76KST.I)(`Command failed: ${command} ${args.join(" ")}`)); throw err; } } function resolveCommandEnv(params) { const baseEnv = params.baseEnv ?? _nodeProcess.default.env; const argv = params.argv; const shouldSuppressNpmFund = (() => { const cmd = _nodePath.default.basename(argv[0] ?? ""); if (cmd === "npm" || cmd === "npm.cmd" || cmd === "npm.exe") return true; if (cmd === "node" || cmd === "node.exe") return (argv[1] ?? "").includes("npm-cli.js"); return false; })(); const mergedEnv = params.env ? { ...baseEnv, ...params.env } : { ...baseEnv }; const resolvedEnv = Object.fromEntries(Object.entries(mergedEnv).filter(([, value]) => value !== void 0).map(([key, value]) => [key, String(value)])); if (shouldSuppressNpmFund) { if (resolvedEnv.NPM_CONFIG_FUND == null) resolvedEnv.NPM_CONFIG_FUND = "false"; if (resolvedEnv.npm_config_fund == null) resolvedEnv.npm_config_fund = "false"; } return resolvedEnv; } async function runCommandWithTimeout(argv, optionsOrTimeout) { const options = typeof optionsOrTimeout === "number" ? { timeoutMs: optionsOrTimeout } : optionsOrTimeout; const { timeoutMs, cwd, input, env, noOutputTimeoutMs } = options; const { windowsVerbatimArguments } = options; const hasInput = input !== void 0; const resolvedEnv = resolveCommandEnv({ argv, env }); const stdio = resolveCommandStdio({ hasInput, preferInherit: true }); const finalArgv = _nodeProcess.default.platform === "win32" ? resolveNpmArgvForWindows(argv) ?? argv : argv; const resolvedCommand = finalArgv !== argv ? finalArgv[0] ?? "" : resolveCommand(argv[0] ?? ""); const useCmdWrapper = isWindowsBatchCommand(resolvedCommand); const child = (0, _nodeChild_process.spawn)(useCmdWrapper ? _nodeProcess.default.env.ComSpec ?? "cmd.exe" : resolvedCommand, useCmdWrapper ? [ "/d", "/s", "/c", buildCmdExeCommandLine(resolvedCommand, finalArgv.slice(1))] : finalArgv.slice(1), { stdio, cwd, env: resolvedEnv, windowsVerbatimArguments: useCmdWrapper ? true : windowsVerbatimArguments, ...(shouldSpawnWithShell({ resolvedCommand, platform: _nodeProcess.default.platform }) ? { shell: true } : {}) }); return await new Promise((resolve, reject) => { let stdout = ""; let stderr = ""; let settled = false; let timedOut = false; let noOutputTimedOut = false; let noOutputTimer = null; const shouldTrackOutputTimeout = typeof noOutputTimeoutMs === "number" && Number.isFinite(noOutputTimeoutMs) && noOutputTimeoutMs > 0; const clearNoOutputTimer = () => { if (!noOutputTimer) return; clearTimeout(noOutputTimer); noOutputTimer = null; }; const armNoOutputTimer = () => { if (!shouldTrackOutputTimeout || settled) return; clearNoOutputTimer(); noOutputTimer = setTimeout(() => { if (settled) return; noOutputTimedOut = true; if (typeof child.kill === "function") child.kill("SIGKILL"); }, Math.floor(noOutputTimeoutMs)); }; const timer = setTimeout(() => { timedOut = true; if (typeof child.kill === "function") child.kill("SIGKILL"); }, timeoutMs); armNoOutputTimer(); if (hasInput && child.stdin) { child.stdin.write(input ?? ""); child.stdin.end(); } child.stdout?.on("data", (d) => { stdout += d.toString(); armNoOutputTimer(); }); child.stderr?.on("data", (d) => { stderr += d.toString(); armNoOutputTimer(); }); child.on("error", (err) => { if (settled) return; settled = true; clearTimeout(timer); clearNoOutputTimer(); reject(err); }); child.on("close", (code, signal) => { if (settled) return; settled = true; clearTimeout(timer); clearNoOutputTimer(); const termination = noOutputTimedOut ? "no-output-timeout" : timedOut ? "timeout" : signal != null ? "signal" : "exit"; resolve({ pid: child.pid ?? void 0, stdout, stderr, code, signal, killed: child.killed, termination, noOutputTimedOut }); }); }); } //#endregion //#region src/infra/openclaw-root.ts const CORE_PACKAGE_NAMES = new Set(["openclaw"]); async function readPackageName(dir) { try { const raw = await _promises.default.readFile(_nodePath.default.join(dir, "package.json"), "utf-8"); const parsed = JSON.parse(raw); return typeof parsed.name === "string" ? parsed.name : null; } catch { return null; } } function readPackageNameSync(dir) { try { const raw = _nodeFs.default.readFileSync(_nodePath.default.join(dir, "package.json"), "utf-8"); const parsed = JSON.parse(raw); return typeof parsed.name === "string" ? parsed.name : null; } catch { return null; } } async function findPackageRoot(startDir, maxDepth = 12) { for (const current of iterAncestorDirs(startDir, maxDepth)) { const name = await readPackageName(current); if (name && CORE_PACKAGE_NAMES.has(name)) return current; } return null; } function findPackageRootSync(startDir, maxDepth = 12) { for (const current of iterAncestorDirs(startDir, maxDepth)) { const name = readPackageNameSync(current); if (name && CORE_PACKAGE_NAMES.has(name)) return current; } return null; } function* iterAncestorDirs(startDir, maxDepth) { let current = _nodePath.default.resolve(startDir); for (let i = 0; i < maxDepth; i += 1) { yield current; const parent = _nodePath.default.dirname(current); if (parent === current) break; current = parent; } } function candidateDirsFromArgv1(argv1) { const normalized = _nodePath.default.resolve(argv1); const candidates = [_nodePath.default.dirname(normalized)]; try { const resolved = _nodeFs.default.realpathSync(normalized); if (resolved !== normalized) candidates.push(_nodePath.default.dirname(resolved)); } catch {} const parts = normalized.split(_nodePath.default.sep); const binIndex = parts.lastIndexOf(".bin"); if (binIndex > 0 && parts[binIndex - 1] === "node_modules") { const binName = _nodePath.default.basename(normalized); const nodeModulesDir = parts.slice(0, binIndex).join(_nodePath.default.sep); candidates.push(_nodePath.default.join(nodeModulesDir, binName)); } return candidates; } async function resolveOpenClawPackageRoot(opts) { for (const candidate of buildCandidates(opts)) { const found = await findPackageRoot(candidate); if (found) return found; } return null; } function resolveOpenClawPackageRootSync(opts) { for (const candidate of buildCandidates(opts)) { const found = findPackageRootSync(candidate); if (found) return found; } return null; } function buildCandidates(opts) { const candidates = []; if (opts.moduleUrl) try { candidates.push(_nodePath.default.dirname((0, _nodeUrl.fileURLToPath)(opts.moduleUrl))); } catch {} if (opts.argv1) candidates.push(...candidateDirsFromArgv1(opts.argv1)); if (opts.cwd) candidates.push(opts.cwd); return candidates; } //#endregion //#region src/agents/workspace-templates.ts const FALLBACK_TEMPLATE_DIR = _nodePath.default.resolve(_nodePath.default.dirname((0, _nodeUrl.fileURLToPath)("file:///root/.local/share/pnpm/global/5/.pnpm/openclaw@2026.3.8_@napi-rs+canvas@0.1.96_@types+express@5.0.6_hono@4.12.7_node-llama-cpp@3.16.2/node_modules/openclaw/dist/plugin-sdk/run-with-concurrency-2ga3-CMk.js")), "../../docs/reference/templates"); let cachedTemplateDir; let resolvingTemplateDir; async function resolveWorkspaceTemplateDir(opts) { if (cachedTemplateDir) return cachedTemplateDir; if (resolvingTemplateDir) return resolvingTemplateDir; resolvingTemplateDir = (async () => { const moduleUrl = opts?.moduleUrl ?? "file:///root/.local/share/pnpm/global/5/.pnpm/openclaw@2026.3.8_@napi-rs+canvas@0.1.96_@types+express@5.0.6_hono@4.12.7_node-llama-cpp@3.16.2/node_modules/openclaw/dist/plugin-sdk/run-with-concurrency-2ga3-CMk.js"; const argv1 = opts?.argv1 ?? process.argv[1]; const cwd = opts?.cwd ?? process.cwd(); const packageRoot = await resolveOpenClawPackageRoot({ moduleUrl, argv1, cwd }); const candidates = [ packageRoot ? _nodePath.default.join(packageRoot, "docs", "reference", "templates") : null, cwd ? _nodePath.default.resolve(cwd, "docs", "reference", "templates") : null, FALLBACK_TEMPLATE_DIR]. filter(Boolean); for (const candidate of candidates) if (await (0, _loggerU3s76KST.w)(candidate)) { cachedTemplateDir = candidate; return candidate; } cachedTemplateDir = candidates[0] ?? FALLBACK_TEMPLATE_DIR; return cachedTemplateDir; })(); try { return await resolvingTemplateDir; } finally { resolvingTemplateDir = void 0; } } //#endregion //#region src/agents/workspace.ts function resolveDefaultAgentWorkspaceDir(env = process.env, homedir = _nodeOs.default.homedir) { const home = (0, _pathsEFexkPEh.d)(env, homedir); const profile = env.OPENCLAW_PROFILE?.trim(); if (profile && profile.toLowerCase() !== "default") return _nodePath.default.join(home, ".openclaw", `workspace-${profile}`); return _nodePath.default.join(home, ".openclaw", "workspace"); } const DEFAULT_AGENT_WORKSPACE_DIR = exports.h = resolveDefaultAgentWorkspaceDir(); const DEFAULT_AGENTS_FILENAME = exports.m = "AGENTS.md"; const DEFAULT_SOUL_FILENAME = exports.y = "SOUL.md"; const DEFAULT_TOOLS_FILENAME = exports.b = "TOOLS.md"; const DEFAULT_IDENTITY_FILENAME = exports.v = "IDENTITY.md"; const DEFAULT_USER_FILENAME = exports.x = "USER.md"; const DEFAULT_HEARTBEAT_FILENAME = exports._ = "HEARTBEAT.md"; const DEFAULT_BOOTSTRAP_FILENAME = exports.g = "BOOTSTRAP.md"; const DEFAULT_MEMORY_FILENAME = "MEMORY.md"; const DEFAULT_MEMORY_ALT_FILENAME = "memory.md"; const WORKSPACE_STATE_DIRNAME = ".openclaw"; const WORKSPACE_STATE_FILENAME = "workspace-state.json"; const WORKSPACE_STATE_VERSION = 1; const workspaceTemplateCache = /* @__PURE__ */new Map(); let gitAvailabilityPromise = null; const MAX_WORKSPACE_BOOTSTRAP_FILE_BYTES = 2 * 1024 * 1024; const workspaceFileCache = /* @__PURE__ */new Map(); function workspaceFileIdentity(stat, canonicalPath) { return `${canonicalPath}|${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}`; } async function readWorkspaceFileWithGuards(params) { const opened = await openBoundaryFile({ absolutePath: params.filePath, rootPath: params.workspaceDir, boundaryLabel: "workspace root", maxBytes: MAX_WORKSPACE_BOOTSTRAP_FILE_BYTES }); if (!opened.ok) { workspaceFileCache.delete(params.filePath); return opened; } const identity = workspaceFileIdentity(opened.stat, opened.path); const cached = workspaceFileCache.get(params.filePath); if (cached && cached.identity === identity) { _nodeFs.default.closeSync(opened.fd); return { ok: true, content: cached.content }; } try { const content = _nodeFs.default.readFileSync(opened.fd, "utf-8"); workspaceFileCache.set(params.filePath, { content, identity }); return { ok: true, content }; } catch (error) { workspaceFileCache.delete(params.filePath); return { ok: false, reason: "io", error }; } finally { _nodeFs.default.closeSync(opened.fd); } } function stripFrontMatter(content) { if (!content.startsWith("---")) return content; const endIndex = content.indexOf("\n---", 3); if (endIndex === -1) return content; const start = endIndex + 4; let trimmed = content.slice(start); trimmed = trimmed.replace(/^\s+/, ""); return trimmed; } async function loadTemplate(name) { const cached = workspaceTemplateCache.get(name); if (cached) return cached; const pending = (async () => { const templateDir = await resolveWorkspaceTemplateDir(); const templatePath = _nodePath.default.join(templateDir, name); try { return stripFrontMatter(await _promises.default.readFile(templatePath, "utf-8")); } catch { throw new Error(`Missing workspace template: ${name} (${templatePath}). Ensure docs/reference/templates are packaged.`); } })(); workspaceTemplateCache.set(name, pending); try { return await pending; } catch (error) { workspaceTemplateCache.delete(name); throw error; } } async function writeFileIfMissing(filePath, content) { try { await _promises.default.writeFile(filePath, content, { encoding: "utf-8", flag: "wx" }); return true; } catch (err) { if (err.code !== "EEXIST") throw err; return false; } } async function fileExists(filePath) { try { await _promises.default.access(filePath); return true; } catch { return false; } } function resolveWorkspaceStatePath(dir) { return _nodePath.default.join(dir, WORKSPACE_STATE_DIRNAME, WORKSPACE_STATE_FILENAME); } function parseWorkspaceOnboardingState(raw) { try { const parsed = JSON.parse(raw); if (!parsed || typeof parsed !== "object") return null; return { version: WORKSPACE_STATE_VERSION, bootstrapSeededAt: typeof parsed.bootstrapSeededAt === "string" ? parsed.bootstrapSeededAt : void 0, onboardingCompletedAt: typeof parsed.onboardingCompletedAt === "string" ? parsed.onboardingCompletedAt : void 0 }; } catch { return null; } } async function readWorkspaceOnboardingState(statePath) { try { return parseWorkspaceOnboardingState(await _promises.default.readFile(statePath, "utf-8")) ?? { version: WORKSPACE_STATE_VERSION }; } catch (err) { if (err.code !== "ENOENT") throw err; return { version: WORKSPACE_STATE_VERSION }; } } async function writeWorkspaceOnboardingState(statePath, state) { await _promises.default.mkdir(_nodePath.default.dirname(statePath), { recursive: true }); const payload = `${JSON.stringify(state, null, 2)}\n`; const tmpPath = `${statePath}.tmp-${process.pid}-${Date.now().toString(36)}`; try { await _promises.default.writeFile(tmpPath, payload, { encoding: "utf-8" }); await _promises.default.rename(tmpPath, statePath); } catch (err) { await _promises.default.unlink(tmpPath).catch(() => {}); throw err; } } async function hasGitRepo(dir) { try { await _promises.default.stat(_nodePath.default.join(dir, ".git")); return true; } catch { return false; } } async function isGitAvailable() { if (gitAvailabilityPromise) return gitAvailabilityPromise; gitAvailabilityPromise = (async () => { try { return (await runCommandWithTimeout(["git", "--version"], { timeoutMs: 2e3 })).code === 0; } catch { return false; } })(); return gitAvailabilityPromise; } async function ensureGitRepo(dir, isBrandNewWorkspace) { if (!isBrandNewWorkspace) return; if (await hasGitRepo(dir)) return; if (!(await isGitAvailable())) return; try { await runCommandWithTimeout(["git", "init"], { cwd: dir, timeoutMs: 1e4 }); } catch {} } async function ensureAgentWorkspace(params) { const dir = (0, _loggerU3s76KST.D)(params?.dir?.trim() ? params.dir.trim() : DEFAULT_AGENT_WORKSPACE_DIR); await _promises.default.mkdir(dir, { recursive: true }); if (!params?.ensureBootstrapFiles) return { dir }; const agentsPath = _nodePath.default.join(dir, DEFAULT_AGENTS_FILENAME); const soulPath = _nodePath.default.join(dir, DEFAULT_SOUL_FILENAME); const toolsPath = _nodePath.default.join(dir, DEFAULT_TOOLS_FILENAME); const identityPath = _nodePath.default.join(dir, DEFAULT_IDENTITY_FILENAME); const userPath = _nodePath.default.join(dir, DEFAULT_USER_FILENAME); const heartbeatPath = _nodePath.default.join(dir, DEFAULT_HEARTBEAT_FILENAME); const bootstrapPath = _nodePath.default.join(dir, DEFAULT_BOOTSTRAP_FILENAME); const statePath = resolveWorkspaceStatePath(dir); const isBrandNewWorkspace = await (async () => { const templatePaths = [ agentsPath, soulPath, toolsPath, identityPath, userPath, heartbeatPath]; const userContentPaths = [ _nodePath.default.join(dir, "memory"), _nodePath.default.join(dir, DEFAULT_MEMORY_FILENAME), _nodePath.default.join(dir, ".git")]; const paths = [...templatePaths, ...userContentPaths]; return (await Promise.all(paths.map(async (p) => { try { await _promises.default.access(p); return true; } catch { return false; } }))).every((v) => !v); })(); const agentsTemplate = await loadTemplate(DEFAULT_AGENTS_FILENAME); const soulTemplate = await loadTemplate(DEFAULT_SOUL_FILENAME); const toolsTemplate = await loadTemplate(DEFAULT_TOOLS_FILENAME); const identityTemplate = await loadTemplate(DEFAULT_IDENTITY_FILENAME); const userTemplate = await loadTemplate(DEFAULT_USER_FILENAME); const heartbeatTemplate = await loadTemplate(DEFAULT_HEARTBEAT_FILENAME); await writeFileIfMissing(agentsPath, agentsTemplate); await writeFileIfMissing(soulPath, soulTemplate); await writeFileIfMissing(toolsPath, toolsTemplate); await writeFileIfMissing(identityPath, identityTemplate); await writeFileIfMissing(userPath, userTemplate); await writeFileIfMissing(heartbeatPath, heartbeatTemplate); let state = await readWorkspaceOnboardingState(statePath); let stateDirty = false; const markState = (next) => { state = { ...state, ...next }; stateDirty = true; }; const nowIso = () => (/* @__PURE__ */new Date()).toISOString(); let bootstrapExists = await fileExists(bootstrapPath); if (!state.bootstrapSeededAt && bootstrapExists) markState({ bootstrapSeededAt: nowIso() }); if (!state.onboardingCompletedAt && state.bootstrapSeededAt && !bootstrapExists) markState({ onboardingCompletedAt: nowIso() }); if (!state.bootstrapSeededAt && !state.onboardingCompletedAt && !bootstrapExists) { const [identityContent, userContent] = await Promise.all([_promises.default.readFile(identityPath, "utf-8"), _promises.default.readFile(userPath, "utf-8")]); const hasUserContent = await (async () => { const indicators = [ _nodePath.default.join(dir, "memory"), _nodePath.default.join(dir, DEFAULT_MEMORY_FILENAME), _nodePath.default.join(dir, ".git")]; for (const indicator of indicators) try { await _promises.default.access(indicator); return true; } catch {} return false; })(); if (identityContent !== identityTemplate || userContent !== userTemplate || hasUserContent) markState({ onboardingCompletedAt: nowIso() });else { if (!(await writeFileIfMissing(bootstrapPath, await loadTemplate("BOOTSTRAP.md")))) bootstrapExists = await fileExists(bootstrapPath);else bootstrapExists = true; if (bootstrapExists && !state.bootstrapSeededAt) markState({ bootstrapSeededAt: nowIso() }); } } if (stateDirty) await writeWorkspaceOnboardingState(statePath, state); await ensureGitRepo(dir, isBrandNewWorkspace); return { dir, agentsPath, soulPath, toolsPath, identityPath, userPath, heartbeatPath, bootstrapPath }; } async function resolveMemoryBootstrapEntries(resolvedDir) { const candidates = [DEFAULT_MEMORY_FILENAME, DEFAULT_MEMORY_ALT_FILENAME]; const entries = []; for (const name of candidates) { const filePath = _nodePath.default.join(resolvedDir, name); try { await _promises.default.access(filePath); entries.push({ name, filePath }); } catch {} } if (entries.length <= 1) return entries; const seen = /* @__PURE__ */new Set(); const deduped = []; for (const entry of entries) { let key = entry.filePath; try { key = await _promises.default.realpath(entry.filePath); } catch {} if (seen.has(key)) continue; seen.add(key); deduped.push(entry); } return deduped; } async function loadWorkspaceBootstrapFiles(dir) { const resolvedDir = (0, _loggerU3s76KST.D)(dir); const entries = [ { name: DEFAULT_AGENTS_FILENAME, filePath: _nodePath.default.join(resolvedDir, DEFAULT_AGENTS_FILENAME) }, { name: DEFAULT_SOUL_FILENAME, filePath: _nodePath.default.join(resolvedDir, DEFAULT_SOUL_FILENAME) }, { name: DEFAULT_TOOLS_FILENAME, filePath: _nodePath.default.join(resolvedDir, DEFAULT_TOOLS_FILENAME) }, { name: DEFAULT_IDENTITY_FILENAME, filePath: _nodePath.default.join(resolvedDir, DEFAULT_IDENTITY_FILENAME) }, { name: DEFAULT_USER_FILENAME, filePath: _nodePath.default.join(resolvedDir, DEFAULT_USER_FILENAME) }, { name: DEFAULT_HEARTBEAT_FILENAME, filePath: _nodePath.default.join(resolvedDir, DEFAULT_HEARTBEAT_FILENAME) }, { name: DEFAULT_BOOTSTRAP_FILENAME, filePath: _nodePath.default.join(resolvedDir, DEFAULT_BOOTSTRAP_FILENAME) }]; entries.push(...(await resolveMemoryBootstrapEntries(resolvedDir))); const result = []; for (const entry of entries) { const loaded = await readWorkspaceFileWithGuards({ filePath: entry.filePath, workspaceDir: resolvedDir }); if (loaded.ok) result.push({ name: entry.name, path: entry.filePath, content: loaded.content, missing: false });else result.push({ name: entry.name, path: entry.filePath, missing: true }); } return result; } const MINIMAL_BOOTSTRAP_ALLOWLIST = new Set([ DEFAULT_AGENTS_FILENAME, DEFAULT_TOOLS_FILENAME, DEFAULT_SOUL_FILENAME, DEFAULT_IDENTITY_FILENAME, DEFAULT_USER_FILENAME] ); function filterBootstrapFilesForSession(files, sessionKey) { if (!sessionKey || !isSubagentSessionKey(sessionKey) && !isCronSessionKey(sessionKey)) return files; return files.filter((file) => MINIMAL_BOOTSTRAP_ALLOWLIST.has(file.name)); } //#endregion //#region src/agents/agent-scope.ts const log = (0, _loggerU3s76KST.a)("agent-scope"); /** Strip null bytes from paths to prevent ENOTDIR errors. */ function stripNullBytes(s) { return s.replace(/\0/g, ""); } let defaultAgentWarned = false; function listAgentEntries(cfg) { const list = cfg.agents?.list; if (!Array.isArray(list)) return []; return list.filter((entry) => Boolean(entry && typeof entry === "object")); } function listAgentIds(cfg) { const agents = listAgentEntries(cfg); if (agents.length === 0) return [DEFAULT_AGENT_ID]; const seen = /* @__PURE__ */new Set(); const ids = []; for (const entry of agents) { const id = normalizeAgentId(entry?.id); if (seen.has(id)) continue; seen.add(id); ids.push(id); } return ids.length > 0 ? ids : [DEFAULT_AGENT_ID]; } function resolveDefaultAgentId(cfg) { const agents = listAgentEntries(cfg); if (agents.length === 0) return DEFAULT_AGENT_ID; const defaults = agents.filter((agent) => agent?.default); if (defaults.length > 1 && !defaultAgentWarned) { defaultAgentWarned = true; log.warn("Multiple agents marked default=true; using the first entry as default."); } const chosen = (defaults[0] ?? agents[0])?.id?.trim(); return normalizeAgentId(chosen || "main"); } function resolveSessionAgentIds(params) { const defaultAgentId = resolveDefaultAgentId(params.config ?? {}); const explicitAgentIdRaw = typeof params.agentId === "string" ? params.agentId.trim().toLowerCase() : ""; const explicitAgentId = explicitAgentIdRaw ? normalizeAgentId(explicitAgentIdRaw) : null; const sessionKey = params.sessionKey?.trim(); const normalizedSessionKey = sessionKey ? sessionKey.toLowerCase() : void 0; const parsed = normalizedSessionKey ? parseAgentSessionKey(normalizedSessionKey) : null; return { defaultAgentId, sessionAgentId: explicitAgentId ?? (parsed?.agentId ? normalizeAgentId(parsed.agentId) : defaultAgentId) }; } function resolveSessionAgentId(params) { return resolveSessionAgentIds(params).sessionAgentId; } function resolveAgentEntry(cfg, agentId) { const id = normalizeAgentId(agentId); return listAgentEntries(cfg).find((entry) => normalizeAgentId(entry.id) === id); } function resolveAgentConfig(cfg, agentId) { const entry = resolveAgentEntry(cfg, normalizeAgentId(agentId)); if (!entry) return; return { name: typeof entry.name === "string" ? entry.name : void 0, workspace: typeof entry.workspace === "string" ? entry.workspace : void 0, agentDir: typeof entry.agentDir === "string" ? entry.agentDir : void 0, model: typeof entry.model === "string" || entry.model && typeof entry.model === "object" ? entry.model : void 0, skills: Array.isArray(entry.skills) ? entry.skills : void 0, memorySearch: entry.memorySearch, humanDelay: entry.humanDelay, heartbeat: entry.heartbeat, identity: entry.identity, groupChat: entry.groupChat, subagents: typeof entry.subagents === "object" && entry.subagents ? entry.subagents : void 0, sandbox: entry.sandbox, tools: entry.tools }; } function resolveAgentSkillsFilter(cfg, agentId) { return normalizeSkillFilter(resolveAgentConfig(cfg, agentId)?.skills); } function resolveModelPrimary(raw) { if (typeof raw === "string") return raw.trim() || void 0; if (!raw || typeof raw !== "object") return; const primary = raw.primary; if (typeof primary !== "string") return; return primary.trim() || void 0; } function resolveAgentExplicitModelPrimary(cfg, agentId) { const raw = resolveAgentConfig(cfg, agentId)?.model; return resolveModelPrimary(raw); } function resolveAgentEffectiveModelPrimary(cfg, agentId) { return resolveAgentExplicitModelPrimary(cfg, agentId) ?? resolveModelPrimary(cfg.agents?.defaults?.model); } function resolveAgentModelFallbacksOverride(cfg, agentId) { const raw = resolveAgentConfig(cfg, agentId)?.model; if (!raw || typeof raw === "string") return; if (!Object.hasOwn(raw, "fallbacks")) return; return Array.isArray(raw.fallbacks) ? raw.fallbacks : void 0; } function resolveFallbackAgentId(params) { const explicitAgentId = typeof params.agentId === "string" ? params.agentId.trim() : ""; if (explicitAgentId) return normalizeAgentId(explicitAgentId); return resolveAgentIdFromSessionKey(params.sessionKey); } function resolveRunModelFallbacksOverride(params) { if (!params.cfg) return; return resolveAgentModelFallbacksOverride(params.cfg, resolveFallbackAgentId({ agentId: params.agentId, sessionKey: params.sessionKey })); } function hasConfiguredModelFallbacks(params) { const fallbacksOverride = resolveRunModelFallbacksOverride(params); const defaultFallbacks = resolveAgentModelFallbackValues(params.cfg?.agents?.defaults?.model); return (fallbacksOverride ?? defaultFallbacks).length > 0; } function resolveEffectiveModelFallbacks(params) { const agentFallbacksOverride = resolveAgentModelFallbacksOverride(params.cfg, params.agentId); if (!params.hasSessionModelOverride) return agentFallbacksOverride; const defaultFallbacks = resolveAgentModelFallbackValues(params.cfg.agents?.defaults?.model); return agentFallbacksOverride ?? defaultFallbacks; } function resolveAgentWorkspaceDir(cfg, agentId) { const id = normalizeAgentId(agentId); const configured = resolveAgentConfig(cfg, id)?.workspace?.trim(); if (configured) return stripNullBytes((0, _loggerU3s76KST.D)(configured)); if (id === resolveDefaultAgentId(cfg)) { const fallback = cfg.agents?.defaults?.workspace?.trim(); if (fallback) return stripNullBytes((0, _loggerU3s76KST.D)(fallback)); return stripNullBytes(resolveDefaultAgentWorkspaceDir(process.env)); } const stateDir = (0, _pathsEFexkPEh.c)(process.env); return stripNullBytes(_nodePath.default.join(stateDir, `workspace-${id}`)); } function resolveAgentDir(cfg, agentId) { const id = normalizeAgentId(agentId); const configured = resolveAgentConfig(cfg, id)?.agentDir?.trim(); if (configured) return (0, _loggerU3s76KST.D)(configured); const root = (0, _pathsEFexkPEh.c)(process.env); return _nodePath.default.join(root, "agents", id, "agent"); } //#endregion //#region src/utils/run-with-concurrency.ts async function runTasksWithConcurrency(params) { const { tasks, limit, onTaskError } = params; const errorMode = params.errorMode ?? "continue"; if (tasks.length === 0) return { results: [], firstError: void 0, hasError: false }; const resolvedLimit = Math.max(1, Math.min(limit, tasks.length)); const results = Array.from({ length: tasks.length }); let next = 0; let firstError = void 0; let hasError = false; const workers = Array.from({ length: resolvedLimit }, async () => { while (true) { if (errorMode === "stop" && hasError) return; const index = next; next += 1; if (index >= tasks.length) return; try { results[index] = await tasks[index](); } catch (error) { if (!hasError) { firstError = error; hasError = true; } onTaskError?.(error, index); if (errorMode === "stop") return; } } }); await Promise.allSettled(workers); return { results, firstError, hasError }; } //#endregion /* v9-652f89b1effcab73 */