import { c as normalizeOptionalString, s as normalizeOptionalLowercaseString } from "./string-coerce-Bje8XVt9.js";
import { r as normalizeProviderId } from "./provider-id-DMUF3fJY.js";
import { m as resolveSessionAgentIds } from "./agent-scope-DYPLTPla.js";
import { i as getRuntimeConfig } from "./io-CaVVH-CQ.js";
import { t as applyMergePatch } from "./merge-patch-4JQLKKQG.js";
import "./config-B9rKdgUB.js";
import { D as readClaudeCliCredentialsCached, O as readCodexCliCredentialsCached, k as readGeminiCliCredentialsCached, s as loadAuthProfileStoreForRuntime } from "./store-BiKyivJC.js";
import { n as mergePluginTextTransforms, t as applyPluginTextReplacements } from "./plugin-text-transforms-Cg1X2Ubm.js";
import { i as resolvePluginSetupCliBackend } from "./setup-registry-BWKZn3CY.js";
import { t as extractMcpServerMap } from "./bundle-mcp-alJgybOE.js";
import { t as getGlobalHookRunner } from "./hook-runner-global-AYTZJLoc.js";
import { X as resolveRuntimeTextTransforms } from "./provider-runtime-CyFBkHwC.js";
import { t as resolveOpenClawAgentDir } from "./agent-paths-B_wzQ6Ed.js";
import { n as resolveRuntimeCliBackends } from "./model-selection-cli-CJ3hXA9Q.js";
import "./model-selection-9Cp9MDcY.js";
import { n as loadMergedBundleMcpConfig, r as toCliBundleMcpServerConfig } from "./embedded-pi-mcp-C2VOVeUz.js";
import { i as buildBootstrapTruncationReportMeta, n as buildBootstrapInjectionStats, r as buildBootstrapPromptWarning, t as analyzeBootstrapBudget } from "./bootstrap-budget-Cr2k_1LL.js";
import { i as resolveBootstrapContextForRun, r as makeBootstrapWarn } from "./bootstrap-files-BT2c4f6z.js";
import { t as resolveHeartbeatPromptForSystemPrompt } from "./heartbeat-system-prompt-DFimsaUx.js";
import { a as resolveBootstrapMaxChars, o as resolveBootstrapPromptTruncationWarningMode, s as resolveBootstrapTotalMaxChars } from "./google-BIuha9qa.js";
import "./pi-embedded-helpers-C0qOhTqd.js";
import { s as resolveSkillsPromptForRun } from "./workspace-BwtJHCO7.js";
import "./skills-D1FmbcAq.js";
import { t as resolveSystemPromptOverride } from "./system-prompt-override-BMQuXqVZ.js";
import { t as buildSystemPromptReport } from "./system-prompt-report-C22OLR9L.js";
import { c as resolveAttemptPrependSystemContext, l as resolvePromptBuildHookResult } from "./attempt.prompt-helpers-zZC_flQo.js";
import { n as composeSystemPromptWithHookContext } from "./attempt.thread-helpers-0CqxcVYg.js";
import { n as resolveRunWorkspaceDir, t as redactRunIdentifier } from "./workspace-run-DvyQ08pn.js";
import { a as hashCliSessionText, o as resolveCliSessionReuse } from "./cli-session-B1KA0FLb.js";
import { n as loadCliSessionHistoryMessages, r as loadCliSessionReseedMessages, t as buildCliSessionHistoryPrompt } from "./session-history-BTjT1txL.js";
import { r as cliBackendLog } from "./log-oF5pzCgQ.js";
import { i as normalizeCliModel, n as buildSystemPrompt, p as serializeTomlInlineValue } from "./helpers-D-tyhpId.js";
import { a as getActiveMcpLoopbackRuntime, i as createMcpLoopbackServerConfig, n as ensureMcpLoopbackServer } from "./mcp-http-jE0j1fiV.js";
import path from "node:path";
import fs from "node:fs/promises";
import os from "node:os";
import crypto from "node:crypto";
const cliAuthEpochDeps = {
	readClaudeCliCredentialsCached,
	readCodexCliCredentialsCached,
	readGeminiCliCredentialsCached,
	loadAuthProfileStoreForRuntime
};
function hashCliAuthEpochPart(value) {
	return crypto.createHash("sha256").update(value).digest("hex");
}
function encodeUnknown(value) {
	return JSON.stringify(value ?? null);
}
function encodeOAuthIdentity(credential) {
	return JSON.stringify([
		"oauth",
		credential.provider,
		credential.clientId ?? null,
		credential.email ?? null,
		credential.enterpriseUrl ?? null,
		credential.projectId ?? null,
		credential.accountId ?? null
	]);
}
function encodeClaudeCredential(credential) {
	if (credential.type === "oauth") return encodeOAuthIdentity(credential);
	return JSON.stringify([
		"token",
		credential.provider,
		credential.token
	]);
}
function encodeCodexCredential(credential) {
	return encodeOAuthIdentity(credential);
}
function encodeGeminiCredential(credential) {
	return encodeOAuthIdentity(credential);
}
function encodeAuthProfileCredential(credential) {
	switch (credential.type) {
		case "api_key": return JSON.stringify([
			"api_key",
			credential.provider,
			credential.key ?? null,
			encodeUnknown(credential.keyRef),
			credential.email ?? null,
			credential.displayName ?? null,
			encodeUnknown(credential.metadata)
		]);
		case "token": return JSON.stringify([
			"token",
			credential.provider,
			credential.token ?? null,
			encodeUnknown(credential.tokenRef),
			credential.email ?? null,
			credential.displayName ?? null
		]);
		case "oauth": return encodeOAuthIdentity(credential);
	}
	throw new Error("Unsupported auth profile credential type");
}
function getLocalCliCredentialFingerprint(provider) {
	switch (provider) {
		case "claude-cli": {
			const credential = cliAuthEpochDeps.readClaudeCliCredentialsCached({
				ttlMs: 5e3,
				allowKeychainPrompt: false
			});
			return credential ? hashCliAuthEpochPart(encodeClaudeCredential(credential)) : void 0;
		}
		case "codex-cli": {
			const credential = cliAuthEpochDeps.readCodexCliCredentialsCached({ ttlMs: 5e3 });
			return credential ? hashCliAuthEpochPart(encodeCodexCredential(credential)) : void 0;
		}
		case "google-gemini-cli": {
			const credential = cliAuthEpochDeps.readGeminiCliCredentialsCached({ ttlMs: 5e3 });
			return credential ? hashCliAuthEpochPart(encodeGeminiCredential(credential)) : void 0;
		}
		default: return;
	}
}
function getAuthProfileCredential(store, authProfileId) {
	if (!authProfileId) return;
	return store.profiles[authProfileId];
}
async function resolveCliAuthEpoch(params) {
	const provider = params.provider.trim();
	const authProfileId = normalizeOptionalString(params.authProfileId);
	const parts = [];
	if (params.skipLocalCredential !== true) {
		const localFingerprint = getLocalCliCredentialFingerprint(provider);
		if (localFingerprint) parts.push(`local:${provider}:${localFingerprint}`);
	}
	if (authProfileId) {
		const credential = getAuthProfileCredential(cliAuthEpochDeps.loadAuthProfileStoreForRuntime(void 0, {
			readOnly: true,
			allowKeychainPrompt: false
		}), authProfileId);
		if (credential) parts.push(`profile:${authProfileId}:${hashCliAuthEpochPart(encodeAuthProfileCredential(credential))}`);
	}
	if (parts.length === 0) return;
	return hashCliAuthEpochPart(parts.join("\n"));
}
let cliBackendsDeps = {
	resolvePluginSetupCliBackend,
	resolveRuntimeCliBackends
};
const FALLBACK_CLI_BACKEND_POLICIES = {};
function normalizeBundleMcpMode(mode, enabled) {
	if (!enabled) return;
	return mode ?? "claude-config-file";
}
function resolveSetupCliBackendPolicy(provider) {
	const entry = cliBackendsDeps.resolvePluginSetupCliBackend({ backend: provider });
	if (!entry) return;
	return {
		bundleMcp: entry.backend.bundleMcp === true,
		bundleMcpMode: normalizeBundleMcpMode(entry.backend.bundleMcpMode, entry.backend.bundleMcp === true),
		baseConfig: entry.backend.config,
		normalizeConfig: entry.backend.normalizeConfig,
		transformSystemPrompt: entry.backend.transformSystemPrompt,
		textTransforms: entry.backend.textTransforms,
		defaultAuthProfileId: entry.backend.defaultAuthProfileId,
		authEpochMode: entry.backend.authEpochMode,
		prepareExecution: entry.backend.prepareExecution
	};
}
function resolveFallbackCliBackendPolicy(provider) {
	return FALLBACK_CLI_BACKEND_POLICIES[provider] ?? resolveSetupCliBackendPolicy(provider);
}
function normalizeBackendKey(key) {
	return normalizeProviderId(key);
}
function pickBackendConfig(config, normalizedId) {
	const directKey = Object.keys(config).find((key) => normalizeOptionalLowercaseString(key) === normalizedId);
	if (directKey) return config[directKey];
	for (const [key, entry] of Object.entries(config)) if (normalizeBackendKey(key) === normalizedId) return entry;
}
function resolveRegisteredBackend(provider) {
	const normalized = normalizeBackendKey(provider);
	return cliBackendsDeps.resolveRuntimeCliBackends().find((entry) => normalizeBackendKey(entry.id) === normalized);
}
function mergeBackendConfig(base, override) {
	if (!override) return { ...base };
	const baseFresh = base.reliability?.watchdog?.fresh ?? {};
	const baseResume = base.reliability?.watchdog?.resume ?? {};
	const overrideFresh = override.reliability?.watchdog?.fresh ?? {};
	const overrideResume = override.reliability?.watchdog?.resume ?? {};
	return {
		...base,
		...override,
		args: override.args ?? base.args,
		env: {
			...base.env,
			...override.env
		},
		modelAliases: {
			...base.modelAliases,
			...override.modelAliases
		},
		clearEnv: Array.from(new Set([...base.clearEnv ?? [], ...override.clearEnv ?? []])),
		sessionIdFields: override.sessionIdFields ?? base.sessionIdFields,
		sessionArgs: override.sessionArgs ?? base.sessionArgs,
		resumeArgs: override.resumeArgs ?? base.resumeArgs,
		reliability: {
			...base.reliability,
			...override.reliability,
			watchdog: {
				...base.reliability?.watchdog,
				...override.reliability?.watchdog,
				fresh: {
					...baseFresh,
					...overrideFresh
				},
				resume: {
					...baseResume,
					...overrideResume
				}
			}
		}
	};
}
function resolveCliBackendConfig(provider, cfg, options = {}) {
	const normalized = normalizeBackendKey(provider);
	const normalizeContext = {
		backendId: normalized,
		...options.agentId ? { agentId: options.agentId } : {},
		...cfg ? { config: cfg } : {}
	};
	const runtimeTextTransforms = resolveRuntimeTextTransforms();
	const override = pickBackendConfig(cfg?.agents?.defaults?.cliBackends ?? {}, normalized);
	const registered = resolveRegisteredBackend(normalized);
	if (registered) {
		const merged = mergeBackendConfig(registered.config, override);
		const config = registered.normalizeConfig ? registered.normalizeConfig(merged, normalizeContext) : merged;
		const command = config.command?.trim();
		if (!command) return null;
		return {
			id: normalized,
			config: {
				...config,
				command
			},
			bundleMcp: registered.bundleMcp === true,
			bundleMcpMode: normalizeBundleMcpMode(registered.bundleMcpMode, registered.bundleMcp === true),
			pluginId: registered.pluginId,
			transformSystemPrompt: registered.transformSystemPrompt,
			textTransforms: mergePluginTextTransforms(runtimeTextTransforms, registered.textTransforms),
			defaultAuthProfileId: registered.defaultAuthProfileId,
			authEpochMode: registered.authEpochMode,
			prepareExecution: registered.prepareExecution
		};
	}
	const fallbackPolicy = resolveFallbackCliBackendPolicy(normalized);
	if (!override) {
		if (!fallbackPolicy?.baseConfig) return null;
		const baseConfig = fallbackPolicy.normalizeConfig ? fallbackPolicy.normalizeConfig(fallbackPolicy.baseConfig, normalizeContext) : fallbackPolicy.baseConfig;
		const command = baseConfig.command?.trim();
		if (!command) return null;
		return {
			id: normalized,
			config: {
				...baseConfig,
				command
			},
			bundleMcp: fallbackPolicy.bundleMcp,
			bundleMcpMode: fallbackPolicy.bundleMcpMode,
			transformSystemPrompt: fallbackPolicy.transformSystemPrompt,
			textTransforms: mergePluginTextTransforms(runtimeTextTransforms, fallbackPolicy.textTransforms),
			defaultAuthProfileId: fallbackPolicy.defaultAuthProfileId,
			authEpochMode: fallbackPolicy.authEpochMode,
			prepareExecution: fallbackPolicy.prepareExecution
		};
	}
	const mergedFallback = fallbackPolicy?.baseConfig ? mergeBackendConfig(fallbackPolicy.baseConfig, override) : override;
	const config = fallbackPolicy?.normalizeConfig ? fallbackPolicy.normalizeConfig(mergedFallback, normalizeContext) : mergedFallback;
	const command = config.command?.trim();
	if (!command) return null;
	return {
		id: normalized,
		config: {
			...config,
			command
		},
		bundleMcp: fallbackPolicy?.bundleMcp === true,
		bundleMcpMode: fallbackPolicy?.bundleMcpMode,
		transformSystemPrompt: fallbackPolicy?.transformSystemPrompt,
		textTransforms: mergePluginTextTransforms(runtimeTextTransforms, fallbackPolicy?.textTransforms),
		defaultAuthProfileId: fallbackPolicy?.defaultAuthProfileId,
		authEpochMode: fallbackPolicy?.authEpochMode,
		prepareExecution: fallbackPolicy?.prepareExecution
	};
}
//#endregion
//#region src/agents/cli-runner/bundle-mcp-adapter-shared.ts
function isRecord(value) {
	return typeof value === "object" && value !== null && !Array.isArray(value);
}
function normalizeStringArray(value) {
	return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? [...value] : void 0;
}
function normalizeStringRecord(value) {
	if (!isRecord(value)) return;
	const entries = Object.entries(value).filter((entry) => {
		return typeof entry[1] === "string";
	});
	return entries.length > 0 ? Object.fromEntries(entries) : void 0;
}
function decodeHeaderEnvPlaceholder(value) {
	const bearerMatch = /^Bearer \${([A-Z0-9_]+)}$/.exec(value);
	if (bearerMatch) return {
		envVar: bearerMatch[1],
		bearer: true
	};
	const envMatch = /^\${([A-Z0-9_]+)}$/.exec(value);
	if (envMatch) return {
		envVar: envMatch[1],
		bearer: false
	};
	return null;
}
function applyCommonServerConfig(next, server) {
	if (typeof server.command === "string") next.command = server.command;
	const args = normalizeStringArray(server.args);
	if (args) next.args = args;
	const env = normalizeStringRecord(server.env);
	if (env) next.env = env;
	if (typeof server.cwd === "string") next.cwd = server.cwd;
	if (typeof server.url === "string") next.url = server.url;
}
//#endregion
//#region src/agents/cli-runner/bundle-mcp-claude.ts
function findClaudeMcpConfigPath(args) {
	if (!args?.length) return;
	for (let i = 0; i < args.length; i += 1) {
		const arg = args[i] ?? "";
		if (arg === "--mcp-config") return normalizeOptionalString(args[i + 1]);
		if (arg.startsWith("--mcp-config=")) return normalizeOptionalString(arg.slice(13));
	}
}
function injectClaudeMcpConfigArgs(args, mcpConfigPath) {
	const next = [];
	for (let i = 0; i < (args?.length ?? 0); i += 1) {
		const arg = args?.[i] ?? "";
		if (arg === "--strict-mcp-config") continue;
		if (arg === "--mcp-config") {
			i += 1;
			continue;
		}
		if (arg.startsWith("--mcp-config=")) continue;
		next.push(arg);
	}
	next.push("--strict-mcp-config", "--mcp-config", mcpConfigPath);
	return next;
}
//#endregion
//#region src/agents/cli-runner/bundle-mcp-codex.ts
function isOpenClawLoopbackMcpServer(name, server) {
	return name === "openclaw" && typeof server.url === "string" && /^https?:\/\/(?:127\.0\.0\.1|localhost):\d+\/mcp(?:[?#].*)?$/.test(server.url);
}
function normalizeCodexServerConfig(name, server) {
	const next = {};
	applyCommonServerConfig(next, server);
	if (isOpenClawLoopbackMcpServer(name, server)) next.default_tools_approval_mode = "approve";
	const httpHeaders = normalizeStringRecord(server.headers);
	if (httpHeaders) {
		const staticHeaders = {};
		const envHeaders = {};
		for (const [name, value] of Object.entries(httpHeaders)) {
			const decoded = decodeHeaderEnvPlaceholder(value);
			if (!decoded) {
				staticHeaders[name] = value;
				continue;
			}
			if (decoded.bearer && normalizeOptionalLowercaseString(name) === "authorization") {
				next.bearer_token_env_var = decoded.envVar;
				continue;
			}
			envHeaders[name] = decoded.envVar;
		}
		if (Object.keys(staticHeaders).length > 0) next.http_headers = staticHeaders;
		if (Object.keys(envHeaders).length > 0) next.env_http_headers = envHeaders;
	}
	return next;
}
function injectCodexMcpConfigArgs(args, config) {
	const overrides = serializeTomlInlineValue(Object.fromEntries(Object.entries(config.mcpServers).map(([name, server]) => [name, normalizeCodexServerConfig(name, server)])));
	return [
		...args ?? [],
		"-c",
		`mcp_servers=${overrides}`
	];
}
//#endregion
//#region src/agents/cli-runner/bundle-mcp-gemini.ts
async function readJsonObject(filePath) {
	try {
		const raw = JSON.parse(await fs.readFile(filePath, "utf-8"));
		return raw && typeof raw === "object" && !Array.isArray(raw) ? { ...raw } : {};
	} catch {
		return {};
	}
}
function resolveEnvPlaceholder(value, inheritedEnv) {
	const decoded = decodeHeaderEnvPlaceholder(value);
	if (!decoded) return value;
	const resolved = inheritedEnv?.[decoded.envVar] ?? process.env[decoded.envVar] ?? "";
	return decoded.bearer ? `Bearer ${resolved}` : resolved;
}
function normalizeGeminiServerConfig(server, inheritedEnv) {
	const next = {};
	applyCommonServerConfig(next, server);
	if (typeof server.type === "string") next.type = server.type;
	const headers = normalizeStringRecord(server.headers);
	if (headers) next.headers = Object.fromEntries(Object.entries(headers).map(([name, value]) => [name, resolveEnvPlaceholder(value, inheritedEnv)]));
	if (typeof server.trust === "boolean") next.trust = server.trust;
	return next;
}
async function writeGeminiSystemSettings(mergedConfig, inheritedEnv) {
	const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-gemini-mcp-"));
	const settingsPath = path.join(tempDir, "settings.json");
	const existingSettingsPath = inheritedEnv?.GEMINI_CLI_SYSTEM_SETTINGS_PATH ?? process.env.GEMINI_CLI_SYSTEM_SETTINGS_PATH;
	const base = typeof existingSettingsPath === "string" && existingSettingsPath.trim() ? await readJsonObject(existingSettingsPath) : {};
	const normalizedConfig = { mcpServers: Object.fromEntries(Object.entries(mergedConfig.mcpServers).map(([name, server]) => [name, normalizeGeminiServerConfig(server, inheritedEnv)])) };
	const settings = applyMergePatch(base, {
		mcp: { allowed: Object.keys(normalizedConfig.mcpServers) },
		mcpServers: normalizedConfig.mcpServers
	});
	if (!isRecord(settings.mcp) || !isRecord(settings.mcpServers)) throw new Error("Gemini MCP settings merge produced an invalid object");
	await fs.writeFile(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
	return {
		env: {
			...inheritedEnv,
			GEMINI_CLI_SYSTEM_SETTINGS_PATH: settingsPath
		},
		cleanup: async () => {
			await fs.rm(tempDir, {
				recursive: true,
				force: true
			});
		}
	};
}
//#endregion
//#region src/agents/cli-runner/bundle-mcp.ts
function resolveBundleMcpMode(mode) {
	return mode ?? "claude-config-file";
}
async function readExternalMcpConfig(configPath) {
	try {
		return { mcpServers: extractMcpServerMap(JSON.parse(await fs.readFile(configPath, "utf-8"))) };
	} catch {
		return { mcpServers: {} };
	}
}
function sortJsonValue(value) {
	if (Array.isArray(value)) return value.map((entry) => sortJsonValue(entry));
	if (!isRecord(value)) return value;
	return Object.fromEntries(Object.keys(value).toSorted().map((key) => [key, sortJsonValue(value[key])]));
}
function normalizeOpenClawLoopbackUrl(value) {
	const match = /^(http:\/\/(?:127\.0\.0\.1|localhost|\[::1\])):\d+(\/mcp)$/.exec(value.trim()) ?? void 0;
	if (!match) return value;
	return `${match[1]}:<openclaw-loopback>${match[2]}`;
}
function canonicalizeBundleMcpConfigForResume(config) {
	return { mcpServers: sortJsonValue(Object.fromEntries(Object.entries(config.mcpServers).map(([name, server]) => {
		if (name !== "openclaw" || typeof server.url !== "string") return [name, sortJsonValue(server)];
		return [name, sortJsonValue({
			...server,
			url: normalizeOpenClawLoopbackUrl(server.url)
		})];
	}))) };
}
async function prepareModeSpecificBundleMcpConfig(params) {
	const serializedConfig = `${JSON.stringify(params.mergedConfig, null, 2)}\n`;
	const mcpConfigHash = crypto.createHash("sha256").update(serializedConfig).digest("hex");
	const serializedResumeConfig = `${JSON.stringify(canonicalizeBundleMcpConfigForResume(params.mergedConfig), null, 2)}\n`;
	const mcpResumeHash = crypto.createHash("sha256").update(serializedResumeConfig).digest("hex");
	if (params.mode === "codex-config-overrides") return {
		backend: {
			...params.backend,
			args: injectCodexMcpConfigArgs(params.backend.args, params.mergedConfig),
			resumeArgs: injectCodexMcpConfigArgs(params.backend.resumeArgs ?? params.backend.args ?? [], params.mergedConfig)
		},
		mcpConfigHash,
		mcpResumeHash,
		env: params.env
	};
	if (params.mode === "gemini-system-settings") {
		const settings = await writeGeminiSystemSettings(params.mergedConfig, params.env);
		return {
			backend: params.backend,
			mcpConfigHash,
			mcpResumeHash,
			env: settings.env,
			cleanup: settings.cleanup
		};
	}
	const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-cli-mcp-"));
	const mcpConfigPath = path.join(tempDir, "mcp.json");
	await fs.writeFile(mcpConfigPath, serializedConfig, "utf-8");
	return {
		backend: {
			...params.backend,
			args: injectClaudeMcpConfigArgs(params.backend.args, mcpConfigPath),
			resumeArgs: injectClaudeMcpConfigArgs(params.backend.resumeArgs ?? params.backend.args ?? [], mcpConfigPath)
		},
		mcpConfigHash,
		mcpResumeHash,
		env: params.env,
		cleanup: async () => {
			await fs.rm(tempDir, {
				recursive: true,
				force: true
			});
		}
	};
}
async function prepareCliBundleMcpConfig(params) {
	if (!params.enabled) return {
		backend: params.backend,
		env: params.env
	};
	const mode = resolveBundleMcpMode(params.mode);
	const existingMcpConfigPath = mode === "claude-config-file" ? findClaudeMcpConfigPath(params.backend.resumeArgs) ?? findClaudeMcpConfigPath(params.backend.args) : void 0;
	let mergedConfig = { mcpServers: {} };
	if (existingMcpConfigPath) {
		const resolvedExistingPath = path.isAbsolute(existingMcpConfigPath) ? existingMcpConfigPath : path.resolve(params.workspaceDir, existingMcpConfigPath);
		mergedConfig = applyMergePatch(mergedConfig, await readExternalMcpConfig(resolvedExistingPath));
	}
	const bundleConfig = loadMergedBundleMcpConfig({
		workspaceDir: params.workspaceDir,
		cfg: params.config,
		mapConfiguredServer: toCliBundleMcpServerConfig
	});
	for (const diagnostic of bundleConfig.diagnostics) params.warn?.(`bundle MCP skipped for ${diagnostic.pluginId}: ${diagnostic.message}`);
	mergedConfig = applyMergePatch(mergedConfig, bundleConfig.config);
	if (params.additionalConfig) mergedConfig = applyMergePatch(mergedConfig, params.additionalConfig);
	return await prepareModeSpecificBundleMcpConfig({
		mode,
		backend: params.backend,
		mergedConfig,
		env: params.env
	});
}
//#endregion
//#region src/agents/cli-runner/prepare.ts
const prepareDeps = {
	makeBootstrapWarn,
	resolveBootstrapContextForRun,
	getActiveMcpLoopbackRuntime,
	ensureMcpLoopbackServer,
	createMcpLoopbackServerConfig,
	resolveOpenClawReferencePaths: async (params) => (await import("./docs-path-DbD9xkjC.js")).resolveOpenClawReferencePaths(params)
};
function shouldSkipLocalCliCredentialEpoch(params) {
	return Boolean(params.authEpochMode === "profile-only" && params.authProfileId && params.authCredential && params.preparedExecution);
}
async function prepareCliRunContext(params) {
	const started = Date.now();
	const workspaceResolution = resolveRunWorkspaceDir({
		workspaceDir: params.workspaceDir,
		sessionKey: params.sessionKey,
		agentId: params.agentId,
		config: params.config
	});
	const resolvedWorkspace = workspaceResolution.workspaceDir;
	const redactedSessionId = redactRunIdentifier(params.sessionId);
	const redactedSessionKey = redactRunIdentifier(params.sessionKey);
	const redactedWorkspace = redactRunIdentifier(resolvedWorkspace);
	if (workspaceResolution.usedFallback) cliBackendLog.warn(`[workspace-fallback] caller=runCliAgent reason=${workspaceResolution.fallbackReason} run=${params.runId} session=${redactedSessionId} sessionKey=${redactedSessionKey} agent=${workspaceResolution.agentId} workspace=${redactedWorkspace}`);
	const workspaceDir = resolvedWorkspace;
	const backendResolved = resolveCliBackendConfig(params.provider, params.config, { agentId: params.agentId });
	if (!backendResolved) throw new Error(`Unknown CLI backend: ${params.provider}`);
	const agentDir = resolveOpenClawAgentDir();
	const effectiveAuthProfileId = (params.authProfileId?.trim() || void 0) ?? backendResolved.defaultAuthProfileId?.trim() ?? void 0;
	let authCredential;
	if (effectiveAuthProfileId) authCredential = loadAuthProfileStoreForRuntime(agentDir, {
		readOnly: true,
		allowKeychainPrompt: false
	}).profiles[effectiveAuthProfileId];
	const extraSystemPrompt = params.extraSystemPrompt?.trim() ?? "";
	const extraSystemPromptHash = params.extraSystemPromptStatic !== void 0 ? hashCliSessionText(params.extraSystemPromptStatic.trim() || void 0) : hashCliSessionText(extraSystemPrompt);
	const modelId = (params.model ?? "default").trim() || "default";
	const normalizedModel = normalizeCliModel(modelId, backendResolved.config);
	const modelDisplay = `${params.provider}/${modelId}`;
	const sessionLabel = params.sessionKey ?? params.sessionId;
	const { bootstrapFiles, contextFiles } = await prepareDeps.resolveBootstrapContextForRun({
		workspaceDir,
		config: params.config,
		sessionKey: params.sessionKey,
		sessionId: params.sessionId,
		warn: prepareDeps.makeBootstrapWarn({
			sessionLabel,
			workspaceDir,
			warn: (message) => cliBackendLog.warn(message)
		})
	});
	const bootstrapMaxChars = resolveBootstrapMaxChars(params.config);
	const bootstrapTotalMaxChars = resolveBootstrapTotalMaxChars(params.config);
	const bootstrapAnalysis = analyzeBootstrapBudget({
		files: buildBootstrapInjectionStats({
			bootstrapFiles,
			injectedFiles: contextFiles
		}),
		bootstrapMaxChars,
		bootstrapTotalMaxChars
	});
	const bootstrapPromptWarningMode = resolveBootstrapPromptTruncationWarningMode(params.config);
	const bootstrapPromptWarning = buildBootstrapPromptWarning({
		analysis: bootstrapAnalysis,
		mode: bootstrapPromptWarningMode,
		seenSignatures: params.bootstrapPromptWarningSignaturesSeen,
		previousSignature: params.bootstrapPromptWarningSignature
	});
	const { defaultAgentId, sessionAgentId } = resolveSessionAgentIds({
		sessionKey: params.sessionKey,
		config: params.config,
		agentId: params.agentId
	});
	let mcpLoopbackRuntime = backendResolved.bundleMcp ? prepareDeps.getActiveMcpLoopbackRuntime() : void 0;
	if (backendResolved.bundleMcp && !mcpLoopbackRuntime) {
		try {
			await prepareDeps.ensureMcpLoopbackServer();
		} catch (error) {
			cliBackendLog.warn(`mcp loopback server failed to start: ${String(error)}`);
		}
		mcpLoopbackRuntime = prepareDeps.getActiveMcpLoopbackRuntime();
	}
	const preparedBackend = await prepareCliBundleMcpConfig({
		enabled: backendResolved.bundleMcp,
		mode: backendResolved.bundleMcpMode,
		backend: backendResolved.config,
		workspaceDir,
		config: params.config,
		additionalConfig: mcpLoopbackRuntime ? prepareDeps.createMcpLoopbackServerConfig(mcpLoopbackRuntime.port) : void 0,
		env: mcpLoopbackRuntime ? {
			OPENCLAW_MCP_TOKEN: params.senderIsOwner === true ? mcpLoopbackRuntime.ownerToken : mcpLoopbackRuntime.nonOwnerToken,
			OPENCLAW_MCP_AGENT_ID: sessionAgentId ?? "",
			OPENCLAW_MCP_ACCOUNT_ID: params.agentAccountId ?? "",
			OPENCLAW_MCP_SESSION_KEY: params.sessionKey ?? "",
			OPENCLAW_MCP_MESSAGE_CHANNEL: params.messageChannel ?? params.messageProvider ?? ""
		} : void 0,
		warn: (message) => cliBackendLog.warn(message)
	});
	const preparedExecution = await backendResolved.prepareExecution?.({
		config: params.config,
		workspaceDir,
		agentDir,
		provider: params.provider,
		modelId,
		authProfileId: effectiveAuthProfileId
	});
	const skipLocalCredentialEpoch = shouldSkipLocalCliCredentialEpoch({
		authEpochMode: backendResolved.authEpochMode,
		authProfileId: effectiveAuthProfileId,
		authCredential,
		preparedExecution
	});
	const authEpoch = await resolveCliAuthEpoch({
		provider: params.provider,
		authProfileId: effectiveAuthProfileId,
		skipLocalCredential: skipLocalCredentialEpoch
	});
	const preparedBackendEnv = preparedExecution?.env && Object.keys(preparedExecution.env).length > 0 ? {
		...preparedBackend.env,
		...preparedExecution.env
	} : preparedBackend.env;
	const preparedBackendCleanup = preparedBackend.cleanup || preparedExecution?.cleanup ? async () => {
		try {
			await preparedExecution?.cleanup?.();
		} finally {
			await preparedBackend.cleanup?.();
		}
	} : void 0;
	const preparedBackendClearEnv = [...preparedBackend.backend.clearEnv ?? [], ...preparedExecution?.clearEnv ?? []];
	const preparedBackendFinal = {
		...preparedBackend,
		backend: {
			...preparedBackend.backend,
			...preparedBackendClearEnv.length > 0 ? { clearEnv: Array.from(new Set(preparedBackendClearEnv)) } : {}
		},
		...preparedBackendEnv ? { env: preparedBackendEnv } : {},
		...preparedBackendCleanup ? { cleanup: preparedBackendCleanup } : {}
	};
	const reusableCliSession = params.cliSessionBinding ? resolveCliSessionReuse({
		binding: params.cliSessionBinding,
		authProfileId: effectiveAuthProfileId,
		authEpoch,
		authEpochVersion: 4,
		extraSystemPromptHash,
		mcpConfigHash: preparedBackendFinal.mcpConfigHash,
		mcpResumeHash: preparedBackendFinal.mcpResumeHash
	}) : params.cliSessionId ? { sessionId: params.cliSessionId } : {};
	if (reusableCliSession.invalidatedReason) cliBackendLog.info(`cli session reset: provider=${params.provider} reason=${reusableCliSession.invalidatedReason}`);
	let openClawHistoryMessages;
	const loadOpenClawHistoryMessages = () => {
		openClawHistoryMessages ??= loadCliSessionHistoryMessages({
			sessionId: params.sessionId,
			sessionFile: params.sessionFile,
			sessionKey: params.sessionKey,
			agentId: params.agentId,
			config: params.config
		});
		return openClawHistoryMessages;
	};
	const heartbeatPrompt = resolveHeartbeatPromptForSystemPrompt({
		config: params.config,
		agentId: sessionAgentId,
		defaultAgentId
	});
	const openClawReferences = await prepareDeps.resolveOpenClawReferencePaths({
		workspaceDir,
		argv1: process.argv[1],
		cwd: process.cwd(),
		moduleUrl: import.meta.url
	});
	const skillsPrompt = resolveSkillsPromptForRun({
		skillsSnapshot: params.skillsSnapshot,
		workspaceDir,
		config: params.config,
		agentId: sessionAgentId
	});
	const builtSystemPrompt = resolveSystemPromptOverride({
		config: params.config,
		agentId: sessionAgentId
	}) ?? buildSystemPrompt({
		workspaceDir,
		config: params.config,
		defaultThinkLevel: params.thinkLevel,
		extraSystemPrompt,
		sourceReplyDeliveryMode: params.sourceReplyDeliveryMode,
		silentReplyPromptMode: params.silentReplyPromptMode,
		ownerNumbers: params.ownerNumbers,
		heartbeatPrompt,
		docsPath: openClawReferences.docsPath ?? void 0,
		sourcePath: openClawReferences.sourcePath ?? void 0,
		skillsPrompt,
		tools: [],
		contextFiles,
		modelDisplay,
		agentId: sessionAgentId
	});
	let systemPrompt = backendResolved.transformSystemPrompt?.({
		config: params.config,
		workspaceDir,
		provider: params.provider,
		modelId,
		modelDisplay,
		agentId: sessionAgentId,
		systemPrompt: builtSystemPrompt
	}) ?? builtSystemPrompt;
	let preparedPrompt = params.prompt;
	const hookRunner = getGlobalHookRunner();
	try {
		const hookResult = await resolvePromptBuildHookResult({
			config: params.config ?? getRuntimeConfig(),
			prompt: params.prompt,
			messages: loadOpenClawHistoryMessages(),
			hookCtx: {
				runId: params.runId,
				agentId: sessionAgentId,
				sessionKey: params.sessionKey,
				sessionId: params.sessionId,
				workspaceDir,
				modelProviderId: params.provider,
				modelId,
				messageProvider: params.messageProvider,
				trigger: params.trigger,
				channelId: params.messageChannel ?? params.messageProvider
			},
			hookRunner
		});
		if (hookResult.prependContext) preparedPrompt = `${hookResult.prependContext}\n\n${preparedPrompt}`;
		if (hookResult.appendContext) preparedPrompt = `${preparedPrompt}\n\n${hookResult.appendContext}`;
		const hookSystemPrompt = hookResult.systemPrompt?.trim();
		if (hookSystemPrompt) systemPrompt = hookSystemPrompt;
		systemPrompt = composeSystemPromptWithHookContext({
			baseSystemPrompt: systemPrompt,
			prependSystemContext: resolveAttemptPrependSystemContext({
				sessionKey: params.sessionKey,
				trigger: params.trigger,
				hookPrependSystemContext: hookResult.prependSystemContext
			}),
			appendSystemContext: hookResult.appendSystemContext
		}) ?? systemPrompt;
	} catch (error) {
		cliBackendLog.warn(`cli prompt-build hook preparation failed: ${String(error)}`);
	}
	const openClawHistoryPrompt = reusableCliSession.sessionId ? void 0 : buildCliSessionHistoryPrompt({
		messages: loadCliSessionReseedMessages({
			sessionId: params.sessionId,
			sessionFile: params.sessionFile,
			sessionKey: params.sessionKey,
			agentId: params.agentId,
			config: params.config
		}),
		prompt: preparedPrompt
	});
	systemPrompt = applyPluginTextReplacements(systemPrompt, backendResolved.textTransforms?.input);
	const systemPromptReport = buildSystemPromptReport({
		source: "run",
		generatedAt: Date.now(),
		sessionId: params.sessionId,
		sessionKey: params.sessionKey,
		provider: params.provider,
		model: modelId,
		workspaceDir,
		bootstrapMaxChars,
		bootstrapTotalMaxChars,
		bootstrapTruncation: buildBootstrapTruncationReportMeta({
			analysis: bootstrapAnalysis,
			warningMode: bootstrapPromptWarningMode,
			warning: bootstrapPromptWarning
		}),
		sandbox: {
			mode: "off",
			sandboxed: false
		},
		systemPrompt,
		bootstrapFiles,
		injectedFiles: contextFiles,
		skillsPrompt,
		tools: []
	});
	return {
		params: preparedPrompt === params.prompt ? params : {
			...params,
			prompt: preparedPrompt
		},
		effectiveAuthProfileId,
		started,
		workspaceDir,
		backendResolved,
		preparedBackend: preparedBackendFinal,
		reusableCliSession,
		modelId,
		normalizedModel,
		systemPrompt,
		systemPromptReport,
		bootstrapPromptWarningLines: bootstrapPromptWarning.lines,
		...openClawHistoryPrompt ? { openClawHistoryPrompt } : {},
		heartbeatPrompt,
		authEpoch,
		authEpochVersion: 4,
		extraSystemPromptHash
	};
}
//#endregion
export { prepareCliRunContext };
