import { n as isTruthyEnvValue } from "./env-C_CibeQY.js";
import { i as formatErrorMessage } from "./errors-DtoeWeWg.js";
import { s as sanitizeHostExecEnv } from "./host-env-security-RnaFYKhk.js";
import { a as shouldLogVerbose } from "./globals-DXby5AAE.js";
import { n as applyPluginTextReplacements } from "./text-transforms.runtime.js";
import { s as emitAgentEvent, t as assertAgentRunLifecycleGenerationCurrent } from "./agent-events-7y1r8HOP.js";
import { o as requestHeartbeat } from "./heartbeat-wake-YhOjrxkC.js";
import { a as enqueueSystemEvent } from "./system-events-D8Q2hfqu.js";
import { r as classifyFailoverReason } from "./errors-Bzy6GE6g.js";
import { d as resolveFailoverStatus, t as FailoverError } from "./failover-error-BWZh2Zvp.js";
import { n as applySkillEnvOverridesFromSnapshot } from "./env-overrides-CkbUnA2K.js";
import { i as scopedHeartbeatWakeOptionsForPolicy, n as resolveEventSessionRoutingPolicy, t as resolveEventSessionKeyForPolicy } from "./event-session-routing-D1lrP0sT.js";
import "./embedded-agent-helpers-H1UQP42s.js";
import { t as shouldUseInternalSourceReplySink } from "./internal-source-reply-C60YbvU4.js";
import { n as appendBootstrapPromptWarning } from "./bootstrap-budget-bmmzkOyn.js";
import { a as isMessagingToolSendAction, i as isMessagingToolDeliveryAction, o as isMessagingToolTargetEvidenceAction, r as isMessagingTool } from "./embedded-agent-messaging-nFT7JKhh.js";
import { a as extractMessagingToolSendResult, i as extractMessagingToolSend, m as sanitizeToolResult, n as collectMessagingMediaUrlsFromRecord, o as extractMessagingToolSourceReplyPayload, p as sanitizeToolArgs, r as collectMessagingMediaUrlsFromToolResult } from "./embedded-agent-subscribe.tools-Cd3J5mMp.js";
import { n as isDeliveredMessagingToolResult, t as isDeliveredMessageToolOnlySourceReplyResult } from "./embedded-agent-message-tool-source-reply-Feic-zms.js";
import { t as getProcessSupervisor } from "./supervisor-BwLG8fjV.js";
import { t as attachCliMessagingDeliveryEvidence } from "./delivery-evidence-Cmz7UHq4.js";
import { i as formatCliBackendOutputDigest, r as cliBackendLog } from "./log-DmQ8IbJr.js";
import { g as waitForMcpLoopbackToolCallCaptureIdle, r as clearMcpLoopbackToolCallCapture, t as beginMcpLoopbackToolCallCapture } from "./mcp-http.loopback-runtime-BhAorXNb.js";
import { a as shouldUseClaudeLiveSession, c as parseCliOutput, i as runClaudeLiveSessionTurn, o as createCliJsonlStreamingParser, r as rotateClaudeLiveMcpCaptureKeyForContext, s as extractCliErrorMessage } from "./claude-live-session-CzS-gN6B.js";
import { n as prepareCliBundleMcpCaptureAttempt, t as prepareClaudeCliSkillsPlugin } from "./claude-skills-plugin-BEjYsNyb.js";
import { c as resolvePromptInput, d as writeCliSystemPromptFile, f as buildCliSupervisorScopeKey, i as enqueueCliRun, l as resolveSessionIdToSend, m as resolveCliRunTimeoutOverrideMs, o as prepareCliPromptImagePayload, p as resolveCliNoOutputTimeoutMs, r as buildCliArgs, s as resolveCliRunQueueKey, t as buildClaudeOwnerKey, u as resolveSystemPromptUsage } from "./helpers-Q20gVvk7.js";
import crypto from "node:crypto";
//#region src/agents/cli-runner/execute.ts
/**
* Executes prepared CLI backend runs, including env isolation, streaming parse,
* live-session routing, and diagnostics.
*/
const executeDeps = {
	getProcessSupervisor,
	enqueueSystemEvent,
	requestHeartbeat,
	writeCliSystemPromptFile
};
const CLI_RUNNER_OUTPUT_TAIL_BYTES = 64 * 1024;
const CLI_RUNNER_OUTPUT_PARSE_BYTES = 1024 * 1024;
const CLI_MESSAGING_EVIDENCE_MAX_CALLS = 64;
const CLI_MCP_DELIVERY_DRAIN_GRACE_MS = 5e3;
const CLI_MCP_REQUEST_ADMISSION_GRACE_MS = 250;
const OPENCLAW_MCP_TOOL_PREFIX = "mcp__openclaw__";
function normalizeCliMessagingToolName(toolName) {
	return toolName.startsWith(OPENCLAW_MCP_TOOL_PREFIX) ? toolName.slice(15) : toolName;
}
function extractCliMessagingTarget(context, toolName, args) {
	const normalizedToolName = normalizeCliMessagingToolName(toolName);
	const currentProvider = context.params.messageChannel ?? context.params.messageProvider;
	const hasExplicitProvider = typeof args.provider === "string" && args.provider.trim().length > 0 || typeof args.channel === "string" && args.channel.trim().length > 0;
	const targetArgs = normalizedToolName === "message" && currentProvider && !hasExplicitProvider ? {
		...args,
		provider: currentProvider
	} : args;
	if (!isMessagingToolTargetEvidenceAction(normalizedToolName, targetArgs)) return;
	return extractMessagingToolSend(normalizedToolName, targetArgs, {
		config: context.params.config,
		currentChannelId: context.params.currentChannelId,
		currentThreadId: context.params.currentThreadTs,
		currentMessageId: context.params.currentMessageId
	});
}
function buildMessagingToolSendEvidenceKey(send) {
	return crypto.createHash("sha256").update(JSON.stringify([
		send.tool,
		send.provider,
		send.accountId,
		send.to,
		send.threadId,
		send.threadImplicit,
		send.threadSuppressed,
		send.text,
		send.mediaUrls
	])).digest("hex");
}
function buildCliMcpCaptureKey(context) {
	if (!context.mcpDeliveryCapture) return;
	return crypto.randomUUID();
}
function extractCliMessagingContent(args, result) {
	const text = [
		"message",
		"SendMessage",
		"content",
		"text",
		"caption"
	].map((key) => args[key]).find((value) => typeof value === "string" && value.trim().length > 0);
	const mediaUrls = [...collectMessagingMediaUrlsFromRecord(args), ...collectMessagingMediaUrlsFromToolResult(result)].filter((url, index, all) => all.indexOf(url) === index);
	return {
		...text ? { text } : {},
		...mediaUrls.length > 0 ? { mediaUrls } : {}
	};
}
function appendUniqueCliMessagingEvidence(values, valueKeys, additions) {
	for (const addition of additions) {
		if (!addition || valueKeys.has(addition)) continue;
		if (values.length >= CLI_MESSAGING_EVIDENCE_MAX_CALLS) {
			const removed = values.shift();
			if (removed) valueKeys.delete(removed);
		}
		values.push(addition);
		valueKeys.add(addition);
	}
}
function appendCliOutputTail(tail, chunk) {
	if (!chunk) return tail;
	const chunkBuffer = Buffer.from(chunk);
	if (chunkBuffer.byteLength >= CLI_RUNNER_OUTPUT_TAIL_BYTES) return Buffer.from(chunkBuffer.subarray(chunkBuffer.byteLength - CLI_RUNNER_OUTPUT_TAIL_BYTES));
	const next = Buffer.concat([tail, chunkBuffer], tail.byteLength + chunkBuffer.byteLength);
	if (next.byteLength <= CLI_RUNNER_OUTPUT_TAIL_BYTES) return next;
	return Buffer.from(next.subarray(next.byteLength - CLI_RUNNER_OUTPUT_TAIL_BYTES));
}
function appendCliOutputParseBuffer(buffer, chunk) {
	if (!chunk) return {
		buffer,
		exceeded: false
	};
	const chunkBuffer = Buffer.from(chunk);
	if (buffer.byteLength + chunkBuffer.byteLength > CLI_RUNNER_OUTPUT_PARSE_BYTES) {
		const remainingBytes = CLI_RUNNER_OUTPUT_PARSE_BYTES - buffer.byteLength;
		if (remainingBytes <= 0) return {
			buffer,
			exceeded: true
		};
		return {
			buffer: Buffer.concat([buffer, chunkBuffer.subarray(0, remainingBytes)], CLI_RUNNER_OUTPUT_PARSE_BYTES),
			exceeded: true
		};
	}
	return {
		buffer: Buffer.concat([buffer, chunkBuffer], buffer.byteLength + chunkBuffer.byteLength),
		exceeded: false
	};
}
function createCliAbortError() {
	const error = /* @__PURE__ */ new Error("CLI run aborted");
	error.name = "AbortError";
	return error;
}
function buildCliLogArgs(params) {
	const logArgs = [];
	for (let i = 0; i < params.args.length; i += 1) {
		const arg = params.args[i] ?? "";
		if (arg === params.systemPromptArg) {
			const systemPromptValue = params.args[i + 1] ?? "";
			logArgs.push(arg, `<systemPrompt:${systemPromptValue.length} chars>`);
			i += 1;
			continue;
		}
		if (arg === params.sessionArg) {
			logArgs.push(arg, params.args[i + 1] ?? "");
			i += 1;
			continue;
		}
		if (arg === params.modelArg) {
			logArgs.push(arg, params.args[i + 1] ?? "");
			i += 1;
			continue;
		}
		if (arg === params.imageArg) {
			logArgs.push(arg, "<image>");
			i += 1;
			continue;
		}
		logArgs.push(arg);
	}
	if (params.argsPrompt) {
		const promptIndex = logArgs.indexOf(params.argsPrompt);
		if (promptIndex >= 0) logArgs[promptIndex] = `<prompt:${params.argsPrompt.length} chars>`;
	}
	return logArgs;
}
const CLI_ENV_AUTH_LOG_KEYS = [
	"AI_GATEWAY_API_KEY",
	"ANTHROPIC_API_KEY",
	"ANTHROPIC_API_KEY_OLD",
	"ANTHROPIC_API_TOKEN",
	"ANTHROPIC_AUTH_TOKEN",
	"ANTHROPIC_BASE_URL",
	"ANTHROPIC_CUSTOM_HEADERS",
	"ANTHROPIC_OAUTH_TOKEN",
	"ANTHROPIC_UNIX_SOCKET",
	"AZURE_OPENAI_API_KEY",
	"CLAUDE_CODE_OAUTH_TOKEN",
	"CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST",
	"OPENAI_API_KEY",
	"OPENAI_STEIPETE_API_KEY",
	"OPENROUTER_API_KEY"
];
const CLI_BACKEND_PRESERVE_ENV = "OPENCLAW_LIVE_CLI_BACKEND_PRESERVE_ENV";
function parseCliBackendPreserveEnv(raw) {
	const trimmed = raw?.trim();
	if (!trimmed) return /* @__PURE__ */ new Set();
	if (trimmed.startsWith("[")) try {
		const parsed = JSON.parse(trimmed);
		return new Set(Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : []);
	} catch {
		return /* @__PURE__ */ new Set();
	}
	return new Set(trimmed.split(/[,\s]+/).map((entry) => entry.trim()).filter((entry) => entry.length > 0));
}
function listPresentCliAuthEnvKeys(env) {
	return CLI_ENV_AUTH_LOG_KEYS.filter((key) => {
		const value = env[key];
		return typeof value === "string" && value.length > 0;
	});
}
function formatCliEnvKeyList(keys) {
	return keys.length > 0 ? keys.join(",") : "none";
}
function buildCliEnvMcpLog(childEnv) {
	return [
		`token=${childEnv.OPENCLAW_MCP_TOKEN ? "set" : "missing"}`,
		`sessionKey=${childEnv.OPENCLAW_MCP_SESSION_KEY ? "set" : "<empty>"}`,
		`agentId=${childEnv.OPENCLAW_MCP_AGENT_ID || "<empty>"}`,
		`accountId=${childEnv.OPENCLAW_MCP_ACCOUNT_ID || "<empty>"}`,
		`messageChannel=${childEnv.OPENCLAW_MCP_MESSAGE_CHANNEL || "<empty>"}`
	].join(" ");
}
function fingerprintCliSessionId(sessionId) {
	const trimmed = sessionId?.trim();
	if (!trimmed) return "none";
	return crypto.createHash("sha256").update(trimmed).digest("hex").slice(0, 12);
}
/** Builds the compact execution summary logged before a CLI backend run. */
function buildCliExecLogLine(params) {
	const reuseState = params.reusableSessionId ? "reusable" : params.invalidatedReason ? `invalidated:${params.invalidatedReason}` : "none";
	return [
		`cli exec: provider=${params.provider}`,
		`model=${params.model}`,
		`promptChars=${params.promptChars}`,
		`trigger=${params.trigger ?? "unknown"}`,
		`useResume=${params.useResume ? "true" : "false"}`,
		`session=${params.cliSessionId ? "present" : "none"}`,
		`resumeSession=${params.useResume ? fingerprintCliSessionId(params.resolvedSessionId) : "none"}`,
		`reuse=${reuseState}`,
		`historyPrompt=${params.hasHistoryPrompt ? "present" : "none"}`
	].join(" ");
}
/** Summarizes auth-related env keys preserved or cleared for a CLI child process. */
function buildCliEnvAuthLog(childEnv) {
	const hostKeys = listPresentCliAuthEnvKeys(process.env);
	const childKeys = listPresentCliAuthEnvKeys(childEnv);
	const childKeySet = new Set(childKeys);
	const clearedKeys = hostKeys.filter((key) => !childKeySet.has(key));
	return [
		`host=${formatCliEnvKeyList(hostKeys)}`,
		`child=${formatCliEnvKeyList(childKeys)}`,
		`cleared=${formatCliEnvKeyList(clearedKeys)}`
	].join(" ");
}
/** Executes a prepared CLI run context and returns normalized CLI output. */
async function executePreparedCliRun(context, cliSessionIdToUse) {
	const params = context.params;
	if (params.abortSignal?.aborted) throw createCliAbortError();
	const backend = context.preparedBackend.backend;
	const { sessionId: resolvedSessionId, isNew } = resolveSessionIdToSend({
		backend,
		cliSessionId: cliSessionIdToUse
	});
	const useResume = Boolean(cliSessionIdToUse && resolvedSessionId && backend.resumeArgs && backend.resumeArgs.length > 0);
	const systemPromptArg = resolveSystemPromptUsage({
		backend,
		isNewSession: isNew,
		systemPrompt: context.systemPrompt
	});
	const systemPromptFile = systemPromptArg && (!useResume || backend.systemPromptWhen === "always") ? await executeDeps.writeCliSystemPromptFile({
		backend,
		systemPrompt: systemPromptArg
	}) : void 0;
	const basePrompt = cliSessionIdToUse ? params.prompt : context.openClawHistoryPrompt ?? params.prompt;
	let prompt = applyPluginTextReplacements(appendBootstrapPromptWarning(basePrompt, context.bootstrapPromptWarningLines, { preserveExactPrompt: context.heartbeatPrompt }), context.backendResolved.textTransforms?.input);
	const { prompt: promptWithImages, imagePaths, cleanupImages } = await prepareCliPromptImagePayload({
		backend,
		prompt,
		workspaceDir: context.workspaceDir,
		images: params.images
	});
	prompt = promptWithImages;
	const { argsPrompt, stdin } = resolvePromptInput({
		backend,
		prompt
	});
	const stdinPayload = stdin ?? "";
	const baseArgs = useResume ? backend.resumeArgs ?? backend.args ?? [] : backend.args ?? [];
	const resolvedArgs = useResume ? baseArgs.map((entry) => entry.replaceAll("{sessionId}", resolvedSessionId ?? "")) : baseArgs;
	const fallbackClaudeSkillsPlugin = context.claudeSkillsPluginArgs === void 0 ? await prepareClaudeCliSkillsPlugin({
		backendId: context.backendResolved.id,
		skillsSnapshot: params.skillsSnapshot
	}) : void 0;
	let fallbackClaudeSkillsPluginCleanupOwned = false;
	const claudeSkillsPluginArgs = context.claudeSkillsPluginArgs ?? fallbackClaudeSkillsPlugin?.args ?? [];
	const baseArgsWithSkills = claudeSkillsPluginArgs.length > 0 ? [...resolvedArgs, ...claudeSkillsPluginArgs] : resolvedArgs;
	const executionBaseArgs = context.backendResolved.resolveExecutionArgs?.({
		config: params.config,
		workspaceDir: context.workspaceDir,
		provider: params.provider,
		modelId: context.modelId,
		authProfileId: context.effectiveAuthProfileId,
		thinkingLevel: params.thinkLevel,
		executionMode: params.executionMode ?? "agent",
		useResume,
		baseArgs: baseArgsWithSkills
	}) ?? baseArgsWithSkills;
	const args = buildCliArgs({
		backend,
		baseArgs: Array.from(executionBaseArgs),
		modelId: context.normalizedModel,
		sessionId: resolvedSessionId,
		systemPrompt: systemPromptArg,
		systemPromptFilePath: systemPromptFile?.filePath,
		imagePaths,
		promptArg: argsPrompt,
		useResume
	});
	const claudeOwnerKey = buildClaudeOwnerKey({
		agentAccountId: params.agentAccountId,
		agentId: params.agentId,
		authProfileId: context.effectiveAuthProfileId,
		sessionId: params.sessionId,
		sessionKey: params.sessionKey
	});
	const queueKey = resolveCliRunQueueKey({
		backendId: context.backendResolved.id,
		liveSession: backend.liveSession,
		serialize: backend.serialize,
		runId: params.runId,
		workspaceDir: context.workspaceDir,
		cliSessionId: useResume ? resolvedSessionId : void 0,
		ownerKey: claudeOwnerKey
	});
	let completedOutput;
	let executionError;
	const cleanupOuterResource = async (cleanup) => {
		try {
			await cleanup?.();
		} catch (error) {
			if (completedOutput?.didSendViaMessagingTool === true) {
				cliBackendLog.warn(`CLI outer resource cleanup failed after confirmed message delivery: ${formatErrorMessage(error)}`);
				return;
			}
			if (executionError !== void 0) {
				cliBackendLog.warn(`CLI outer resource cleanup also failed after run error: ${formatErrorMessage(error)}`);
				return;
			}
			throw error;
		}
	};
	try {
		completedOutput = await enqueueCliRun(queueKey, async () => {
			if (params.lifecycleGeneration) assertAgentRunLifecycleGenerationCurrent(params.lifecycleGeneration);
			const cliTurnStartedAt = Date.now();
			const restoreSkillEnv = params.skillsSnapshot ? applySkillEnvOverridesFromSnapshot({
				snapshot: params.skillsSnapshot,
				config: params.config
			}) : void 0;
			let gatewayCaptureKey;
			let cleanupMcpCaptureAttempt;
			let yielded = false;
			let didSendViaMessagingTool = false;
			let didDeliverSourceReplyViaMessageTool = false;
			let inFlightUnclassifiedMcpRequests = 0;
			let inFlightMessagingToolCalls = 0;
			const inFlightPreparedMessagingCalls = /* @__PURE__ */ new Set();
			const pendingMessagingCalls = /* @__PURE__ */ new Map();
			const messagingToolSentTexts = [];
			const messagingToolSentTextKeys = /* @__PURE__ */ new Set();
			const messagingToolSentMediaUrls = [];
			const messagingToolSentMediaUrlKeys = /* @__PURE__ */ new Set();
			const messagingToolSentTargets = [];
			const messagingToolSentTargetKeys = /* @__PURE__ */ new Set();
			const messagingToolSourceReplyPayloads = [];
			const isPreparedInternalSourceReply = async (call) => {
				if (context.params.sourceReplyDeliveryMode !== "message_tool_only" || normalizeCliMessagingToolName(call.toolName) !== "message" || call.args.action !== "send" || !context.params.config) return false;
				return await shouldUseInternalSourceReplySink({
					cfg: context.params.config,
					action: "send",
					sessionKey: context.params.sessionKey,
					sourceReplyDeliveryMode: context.params.sourceReplyDeliveryMode,
					toolContext: {
						currentChannelProvider: context.params.messageChannel ?? context.params.messageProvider,
						currentChannelId: context.params.currentChannelId,
						currentThreadTs: context.params.currentThreadTs,
						currentMessageId: context.params.currentMessageId
					}
				}, call.args);
			};
			let runOutput;
			let runError;
			let runFailed = false;
			const recordRunError = (error) => {
				if (runFailed) return;
				runFailed = true;
				runError = error;
			};
			const withExecutionEvidence = (output) => {
				return {
					...output,
					...yielded ? { yielded: true } : {},
					...didSendViaMessagingTool ? { didSendViaMessagingTool: true } : {},
					...didDeliverSourceReplyViaMessageTool ? { didDeliverSourceReplyViaMessageTool: true } : {},
					...messagingToolSentTexts.length > 0 ? { messagingToolSentTexts: messagingToolSentTexts.slice() } : {},
					...messagingToolSentMediaUrls.length > 0 ? { messagingToolSentMediaUrls: messagingToolSentMediaUrls.slice() } : {},
					...messagingToolSentTargets.length > 0 ? { messagingToolSentTargets: messagingToolSentTargets.slice() } : {},
					...messagingToolSourceReplyPayloads.length > 0 ? { messagingToolSourceReplyPayloads: messagingToolSourceReplyPayloads.slice() } : {}
				};
			};
			try {
				cliBackendLog.info(buildCliExecLogLine({
					provider: params.provider,
					model: context.normalizedModel,
					promptChars: basePrompt.length,
					trigger: params.trigger,
					useResume,
					cliSessionId: cliSessionIdToUse,
					resolvedSessionId,
					reusableSessionId: context.reusableCliSession.sessionId,
					invalidatedReason: context.reusableCliSession.invalidatedReason,
					hasHistoryPrompt: Boolean(context.openClawHistoryPrompt)
				}));
				const logOutputText = isTruthyEnvValue(process.env["OPENCLAW_CLI_BACKEND_LOG_OUTPUT"]) || isTruthyEnvValue(process.env["OPENCLAW_CLAUDE_CLI_LOG_OUTPUT"]);
				const outputMode = useResume ? backend.resumeOutput ?? backend.output : backend.output;
				const hasJsonlOutput = outputMode === "jsonl";
				const initialGatewayCaptureKey = shouldUseClaudeLiveSession(context) ? void 0 : buildCliMcpCaptureKey(context);
				const mcpCaptureAttempt = await prepareCliBundleMcpCaptureAttempt({
					mode: context.backendResolved.bundleMcpMode,
					env: context.preparedBackend.env,
					captureKey: initialGatewayCaptureKey
				});
				cleanupMcpCaptureAttempt = mcpCaptureAttempt.cleanup;
				const env = (() => {
					const next = sanitizeHostExecEnv({
						baseEnv: process.env,
						blockPathOverrides: true
					});
					const preservedEnv = parseCliBackendPreserveEnv(process.env[CLI_BACKEND_PRESERVE_ENV]);
					for (const key of backend.clearEnv ?? []) {
						if (preservedEnv.has(key)) continue;
						delete next[key];
					}
					if (backend.env && Object.keys(backend.env).length > 0) Object.assign(next, sanitizeHostExecEnv({
						baseEnv: {},
						overrides: backend.env,
						blockPathOverrides: true
					}));
					Object.assign(next, mcpCaptureAttempt.env);
					delete next["CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST"];
					return next;
				})();
				if (logOutputText) {
					const logArgs = buildCliLogArgs({
						args,
						systemPromptArg: backend.systemPromptArg,
						sessionArg: backend.sessionArg,
						modelArg: backend.modelArg,
						imageArg: backend.imageArg,
						argsPrompt
					});
					cliBackendLog.info(`cli argv: ${backend.command} ${logArgs.join(" ")}`);
					cliBackendLog.info(`cli env auth: ${buildCliEnvAuthLog(env)}`);
					if (env.OPENCLAW_MCP_TOKEN || env.OPENCLAW_MCP_SESSION_KEY || env.OPENCLAW_MCP_AGENT_ID) cliBackendLog.info(`cli env mcp: ${buildCliEnvMcpLog(env)}`);
				}
				const runTimeoutOverrideMs = resolveCliRunTimeoutOverrideMs({
					config: params.config,
					lane: params.lane,
					timeoutMs: params.timeoutMs,
					runTimeoutOverrideMs: params.runTimeoutOverrideMs
				});
				const noOutputTimeoutMs = resolveCliNoOutputTimeoutMs({
					backend,
					timeoutMs: params.timeoutMs,
					runTimeoutOverrideMs,
					useResume,
					trigger: params.trigger
				});
				const commitMessagingToolResult = (paramsLocal) => {
					if (!isDeliveredMessagingToolResult(paramsLocal)) return;
					didSendViaMessagingTool = true;
					const toolArgs = paramsLocal.args ?? {};
					const isMessagingSend = isMessagingToolSendAction(paramsLocal.toolName, toolArgs);
					const content = isMessagingSend ? extractCliMessagingContent(toolArgs, paramsLocal.result) : {};
					if (isMessagingSend) {
						appendUniqueCliMessagingEvidence(messagingToolSentTexts, messagingToolSentTextKeys, content.text ? [content.text] : []);
						appendUniqueCliMessagingEvidence(messagingToolSentMediaUrls, messagingToolSentMediaUrlKeys, content.mediaUrls ?? []);
						if (isDeliveredMessageToolOnlySourceReplyResult({
							sourceReplyDeliveryMode: context.params.sourceReplyDeliveryMode,
							toolName: paramsLocal.toolName,
							args: paramsLocal.args,
							result: paramsLocal.result,
							isError: paramsLocal.isError
						})) {
							didDeliverSourceReplyViaMessageTool = true;
							const sourceReplyPayload = extractMessagingToolSourceReplyPayload(paramsLocal.result);
							if (sourceReplyPayload) {
								if (messagingToolSourceReplyPayloads.length >= CLI_MESSAGING_EVIDENCE_MAX_CALLS) messagingToolSourceReplyPayloads.shift();
								messagingToolSourceReplyPayloads.push(sourceReplyPayload);
							}
						}
					}
					if (paramsLocal.target) {
						const targetWithContent = {
							...extractMessagingToolSendResult(paramsLocal.target, paramsLocal.result),
							...content
						};
						const evidenceKey = buildMessagingToolSendEvidenceKey(targetWithContent);
						if (messagingToolSentTargetKeys.has(evidenceKey)) return;
						if (messagingToolSentTargets.length >= CLI_MESSAGING_EVIDENCE_MAX_CALLS) {
							const removed = messagingToolSentTargets.shift();
							if (removed) messagingToolSentTargetKeys.delete(buildMessagingToolSendEvidenceKey(removed));
						}
						messagingToolSentTargets.push(targetWithContent);
						messagingToolSentTargetKeys.add(evidenceKey);
					}
				};
				const beginGatewayCapture = (captureKey) => {
					if (!captureKey) return;
					if (gatewayCaptureKey === captureKey) return;
					if (gatewayCaptureKey) throw new Error("CLI MCP capture key changed during an active attempt");
					gatewayCaptureKey = captureKey;
					const isAdmittedPotentialMessagingDelivery = (toolName) => {
						return isMessagingTool(normalizeCliMessagingToolName(toolName));
					};
					const isPreparedMessagingDelivery = (toolName, toolArgs) => {
						return toolArgs.dryRun !== true && isMessagingToolDeliveryAction(normalizeCliMessagingToolName(toolName), toolArgs);
					};
					beginMcpLoopbackToolCallCapture({
						captureKey: gatewayCaptureKey,
						onYield: () => {
							yielded = true;
						},
						onRequestStart: () => {
							inFlightUnclassifiedMcpRequests += 1;
						},
						onRequestClassified: () => {
							inFlightUnclassifiedMcpRequests = Math.max(0, inFlightUnclassifiedMcpRequests - 1);
						},
						onToolCallStart: (call) => {
							if (isAdmittedPotentialMessagingDelivery(call.toolName)) inFlightMessagingToolCalls += 1;
						},
						onToolCallUpdate: ({ previous, current }) => {
							inFlightPreparedMessagingCalls.delete(previous);
							const wasMessagingSend = isAdmittedPotentialMessagingDelivery(previous.toolName);
							const isMessagingSend = isPreparedMessagingDelivery(current.toolName, current.args);
							if (wasMessagingSend !== isMessagingSend) inFlightMessagingToolCalls = Math.max(0, inFlightMessagingToolCalls + (isMessagingSend ? 1 : -1));
							if (isMessagingSend) inFlightPreparedMessagingCalls.add(current);
						},
						onToolCallFinish: (call, { prepared }) => {
							if (prepared ? isPreparedMessagingDelivery(call.toolName, call.args) : isAdmittedPotentialMessagingDelivery(call.toolName)) inFlightMessagingToolCalls = Math.max(0, inFlightMessagingToolCalls - 1);
							inFlightPreparedMessagingCalls.delete(call);
						},
						onToolCallResult: ({ toolName, args: toolArgs, result, isError }) => {
							const normalizedToolName = normalizeCliMessagingToolName(toolName);
							if (!isMessagingToolDeliveryAction(normalizedToolName, toolArgs)) return;
							commitMessagingToolResult({
								toolName: normalizedToolName,
								target: extractCliMessagingTarget(context, normalizedToolName, toolArgs),
								args: toolArgs,
								result,
								isError
							});
						}
					});
				};
				beginGatewayCapture(initialGatewayCaptureKey);
				let observedCliActivity = false;
				const emitLiveEvents = params.executionMode !== "side-question";
				const emitCliToolUseStart = (event) => {
					observedCliActivity = true;
					const toolName = normalizeCliMessagingToolName(event.name);
					if (!gatewayCaptureKey && event.args.dryRun !== true && isMessagingToolDeliveryAction(toolName, event.args)) {
						if (pendingMessagingCalls.size >= CLI_MESSAGING_EVIDENCE_MAX_CALLS) {
							const oldestToolCallId = pendingMessagingCalls.keys().next().value;
							if (oldestToolCallId !== void 0) {
								pendingMessagingCalls.delete(oldestToolCallId);
								didSendViaMessagingTool = true;
							}
						}
						pendingMessagingCalls.set(event.toolCallId, {
							toolName,
							args: event.args,
							target: extractCliMessagingTarget(context, toolName, event.args)
						});
					}
					if (!emitLiveEvents) return;
					emitAgentEvent({
						runId: params.runId,
						stream: "tool",
						data: {
							phase: "start",
							name: event.name,
							toolCallId: event.toolCallId,
							args: sanitizeToolArgs(event.args)
						}
					});
				};
				const emitCliToolResult = (event) => {
					observedCliActivity = true;
					const pending = pendingMessagingCalls.get(event.toolCallId);
					if (pending) {
						pendingMessagingCalls.delete(event.toolCallId);
						commitMessagingToolResult({
							toolName: pending.toolName,
							target: pending.target,
							args: pending.args,
							result: event.result,
							isError: event.isError
						});
					}
					if (!emitLiveEvents) return;
					emitAgentEvent({
						runId: params.runId,
						stream: "tool",
						data: {
							phase: "result",
							name: event.name,
							toolCallId: event.toolCallId,
							isError: event.isError,
							result: sanitizeToolResult(event.result)
						}
					});
				};
				let commentaryCounter = 0;
				const emitCliCommentaryText = (text) => {
					if (!emitLiveEvents) return;
					commentaryCounter += 1;
					const transformedText = applyPluginTextReplacements(text, context.backendResolved.textTransforms?.output);
					emitAgentEvent({
						runId: params.runId,
						stream: "item",
						data: {
							kind: "preamble",
							itemId: `commentary-${params.runId}-${commentaryCounter}`,
							phase: "update",
							title: "commentary",
							status: "running",
							progressText: transformedText
						}
					});
				};
				if (shouldUseClaudeLiveSession(context)) {
					if (!hasJsonlOutput) throw new Error("Claude live session requires JSONL streaming parser");
					params.onExecutionPhase?.({
						phase: "process_spawned",
						provider: params.provider,
						model: context.modelId,
						backend: context.backendResolved.id
					});
					const liveSessionOwnsRunArtifacts = context.mcpDeliveryCapture !== true;
					fallbackClaudeSkillsPluginCleanupOwned = liveSessionOwnsRunArtifacts;
					const ownedPreparedBackendCleanup = liveSessionOwnsRunArtifacts ? context.preparedBackend.cleanup : void 0;
					if (liveSessionOwnsRunArtifacts) context.preparedBackend.cleanup = void 0;
					const liveResult = await runClaudeLiveSessionTurn({
						context,
						args,
						env,
						prompt,
						useResume,
						noOutputTimeoutMs,
						getProcessSupervisor: executeDeps.getProcessSupervisor,
						onAssistantDelta: ({ text, delta }) => {
							if (text || delta) observedCliActivity = true;
							if (!emitLiveEvents) return;
							emitAgentEvent({
								runId: params.runId,
								stream: "assistant",
								data: {
									text: applyPluginTextReplacements(text, context.backendResolved.textTransforms?.output),
									delta: applyPluginTextReplacements(delta, context.backendResolved.textTransforms?.output)
								}
							});
						},
						onToolUseStart: emitCliToolUseStart,
						onToolResult: emitCliToolResult,
						onCommentaryText: emitLiveEvents && context.params.emitCommentaryText ? emitCliCommentaryText : void 0,
						onMcpCaptureReady: beginGatewayCapture,
						cleanup: liveSessionOwnsRunArtifacts ? async () => {
							try {
								await fallbackClaudeSkillsPlugin?.cleanup();
							} finally {
								await ownedPreparedBackendCleanup?.();
							}
						} : async () => {}
					});
					const rawText = liveResult.output.text;
					runOutput = {
						...liveResult.output,
						rawText,
						finalPromptText: prompt,
						text: applyPluginTextReplacements(rawText, context.backendResolved.textTransforms?.output)
					};
				} else {
					const streamingParser = hasJsonlOutput ? createCliJsonlStreamingParser({
						backend,
						providerId: context.backendResolved.id,
						onAssistantDelta: ({ text, delta }) => {
							if (text || delta) observedCliActivity = true;
							if (!emitLiveEvents) return;
							emitAgentEvent({
								runId: params.runId,
								stream: "assistant",
								data: {
									text: applyPluginTextReplacements(text, context.backendResolved.textTransforms?.output),
									delta: applyPluginTextReplacements(delta, context.backendResolved.textTransforms?.output)
								}
							});
						},
						onToolUseStart: emitCliToolUseStart,
						onToolResult: emitCliToolResult,
						onCommentaryText: emitLiveEvents && context.params.emitCommentaryText ? emitCliCommentaryText : void 0
					}) : null;
					const supervisor = executeDeps.getProcessSupervisor();
					const scopeKey = buildCliSupervisorScopeKey({
						backend,
						backendId: context.backendResolved.id,
						cliSessionId: useResume ? resolvedSessionId : void 0
					});
					let stdoutTail = Buffer.alloc(0);
					let stdoutParseBuffer = Buffer.alloc(0);
					let stdoutParseExceeded = false;
					let stderrTail = Buffer.alloc(0);
					let stderrParseBuffer = Buffer.alloc(0);
					let stderrParseExceeded = false;
					params.onExecutionPhase?.({
						phase: "process_spawned",
						provider: params.provider,
						model: context.modelId,
						backend: context.backendResolved.id
					});
					const managedRun = await supervisor.spawn({
						sessionId: params.sessionId,
						backendId: context.backendResolved.id,
						scopeKey,
						replaceExistingScope: Boolean(useResume && scopeKey),
						mode: "child",
						argv: [backend.command, ...args],
						timeoutMs: params.timeoutMs,
						noOutputTimeoutMs,
						cwd: context.cwd ?? context.workspaceDir,
						env,
						input: stdinPayload,
						captureOutput: false,
						onStdout: (chunk) => {
							stdoutTail = appendCliOutputTail(stdoutTail, chunk);
							if (!stdoutParseExceeded) {
								const nextStdoutParse = appendCliOutputParseBuffer(stdoutParseBuffer, chunk);
								stdoutParseBuffer = nextStdoutParse.buffer;
								stdoutParseExceeded = nextStdoutParse.exceeded;
							}
							streamingParser?.push(chunk);
						},
						onStderr: (chunk) => {
							stderrTail = appendCliOutputTail(stderrTail, chunk);
							if (!stderrParseExceeded) {
								const nextStderrParse = appendCliOutputParseBuffer(stderrParseBuffer, chunk);
								stderrParseBuffer = nextStderrParse.buffer;
								stderrParseExceeded = nextStderrParse.exceeded;
							}
						}
					});
					let replyBackendCompleted = false;
					const replyBackendHandle = params.replyOperation ? {
						kind: "cli",
						cancel: () => {
							managedRun.cancel("manual-cancel");
						},
						isStreaming: () => !replyBackendCompleted
					} : void 0;
					if (replyBackendHandle) params.replyOperation?.attachBackend(replyBackendHandle);
					const abortManagedRun = () => {
						managedRun.cancel("manual-cancel");
					};
					params.abortSignal?.addEventListener("abort", abortManagedRun, { once: true });
					if (params.abortSignal?.aborted) abortManagedRun();
					let result;
					try {
						result = await managedRun.wait();
					} finally {
						replyBackendCompleted = true;
						if (replyBackendHandle) params.replyOperation?.detachBackend(replyBackendHandle);
						params.abortSignal?.removeEventListener("abort", abortManagedRun);
					}
					streamingParser?.finish();
					if (params.abortSignal?.aborted && result.reason === "manual-cancel") throw createCliAbortError();
					const stdout = stdoutParseBuffer.toString("utf8").trim();
					const stdoutDiagnostic = stdoutTail.toString("utf8").trim();
					const stderr = stderrParseBuffer.toString("utf8").trim();
					const stderrDiagnostic = stderrTail.toString("utf8").trim();
					if (logOutputText) {
						if (stdoutDiagnostic) cliBackendLog.info(`cli stdout:\n${stdoutDiagnostic}`);
						if (stderrDiagnostic) cliBackendLog.info(`cli stderr:\n${stderrDiagnostic}`);
					}
					if (shouldLogVerbose()) {
						if (stdoutDiagnostic) cliBackendLog.debug(`cli stdout:\n${stdoutDiagnostic}`);
						if (stderrDiagnostic) cliBackendLog.debug(`cli stderr:\n${stderrDiagnostic}`);
					}
					if (result.exitCode !== 0 || result.reason !== "exit") {
						if (result.reason === "no-output-timeout" || result.noOutputTimedOut) {
							const timeoutReason = `CLI produced no output for ${Math.round(noOutputTimeoutMs / 1e3)}s and was terminated.`;
							cliBackendLog.warn(`cli watchdog timeout: provider=${params.provider} model=${context.modelId} session=${resolvedSessionId ?? params.sessionId} noOutputTimeoutMs=${noOutputTimeoutMs} pid=${managedRun.pid ?? "unknown"}`);
							const retryableNoOutputTimeout = !observedCliActivity && stdoutDiagnostic.length === 0 && stderrDiagnostic.length === 0;
							const deferWatchdogNoticeForFreshRetry = retryableNoOutputTimeout && Boolean(cliSessionIdToUse) && Boolean(resolvedSessionId) && Boolean(context.openClawHistoryPrompt) && Boolean(params.sessionKey) && params.timeoutMs - (Date.now() - context.started) > 0;
							if (params.sessionKey && emitLiveEvents && !deferWatchdogNoticeForFreshRetry) {
								const stallNotice = [
									`CLI agent (${params.provider}) produced no output for ${Math.round(noOutputTimeoutMs / 1e3)}s and was terminated.`,
									"It may have been waiting for interactive input or an approval prompt.",
									"For Claude Code, prefer --permission-mode bypassPermissions --print."
								].join(" ");
								const eventRouting = resolveEventSessionRoutingPolicy({
									cfg: params.config,
									sessionKey: params.sessionKey,
									channel: params.messageProvider,
									accountId: params.agentAccountId
								});
								executeDeps.enqueueSystemEvent(stallNotice, { sessionKey: resolveEventSessionKeyForPolicy(params.sessionKey, eventRouting) });
								executeDeps.requestHeartbeat(scopedHeartbeatWakeOptionsForPolicy(params.sessionKey, {
									source: "cli-watchdog",
									intent: "event",
									reason: "cli:watchdog:stall"
								}, eventRouting));
							}
							throw new FailoverError(timeoutReason, {
								reason: "timeout",
								provider: params.provider,
								model: context.modelId,
								sessionId: params.sessionId,
								lane: params.lane,
								status: resolveFailoverStatus("timeout"),
								code: retryableNoOutputTimeout ? "cli_no_output_timeout" : void 0
							});
						}
						if (result.reason === "overall-timeout") throw new FailoverError(`CLI exceeded timeout (${Math.round(params.timeoutMs / 1e3)}s) and was terminated.`, {
							reason: "timeout",
							provider: params.provider,
							model: context.modelId,
							sessionId: params.sessionId,
							lane: params.lane,
							status: resolveFailoverStatus("timeout"),
							code: "cli_overall_timeout"
						});
						const errorCandidates = [
							stderr,
							stdout,
							stderrDiagnostic,
							stdoutDiagnostic
						].filter((candidate) => candidate.length > 0);
						const structuredError = errorCandidates.map((candidate) => extractCliErrorMessage(candidate)).find(Boolean) ?? null;
						let classifiedErrorText = structuredError;
						let reason = structuredError ? classifyFailoverReason(structuredError, { provider: params.provider }) : null;
						if (!reason) for (const candidate of errorCandidates) {
							reason = classifyFailoverReason(candidate, { provider: params.provider });
							if (reason) {
								classifiedErrorText = candidate;
								break;
							}
						}
						const err = structuredError || classifiedErrorText || errorCandidates[0] || "CLI failed.";
						reason = reason ?? "unknown";
						const status = resolveFailoverStatus(reason);
						const retryCode = reason === "unknown" && result.reason === "exit" && errorCandidates.length === 0 && !observedCliActivity ? "cli_unknown_empty_failure" : void 0;
						throw new FailoverError(err, {
							reason,
							provider: params.provider,
							model: context.modelId,
							sessionId: params.sessionId,
							lane: params.lane,
							status,
							code: retryCode
						});
					}
					const streamedJsonlOutput = outputMode === "jsonl" ? streamingParser?.getOutput() ?? null : null;
					if (stdoutParseExceeded && !streamedJsonlOutput) throw new FailoverError(`CLI stdout exceeded ${CLI_RUNNER_OUTPUT_PARSE_BYTES} bytes; refusing to parse truncated output.`, {
						reason: "format",
						provider: params.provider,
						model: context.modelId,
						sessionId: params.sessionId,
						lane: params.lane,
						status: resolveFailoverStatus("format")
					});
					const parsed = streamedJsonlOutput ?? parseCliOutput({
						raw: stdout,
						backend,
						providerId: context.backendResolved.id,
						outputMode,
						fallbackSessionId: resolvedSessionId
					});
					const rawText = parsed.text;
					cliBackendLog.info(`cli turn: provider=${params.provider} model=${context.modelId} durationMs=${Date.now() - cliTurnStartedAt} ${formatCliBackendOutputDigest(rawText)}`);
					runOutput = {
						...parsed,
						rawText,
						finalPromptText: prompt,
						text: applyPluginTextReplacements(rawText, context.backendResolved.textTransforms?.output)
					};
				}
			} catch (error) {
				recordRunError(error);
			} finally {
				try {
					if (!gatewayCaptureKey && pendingMessagingCalls.size > 0) {
						const unresolvedJsonlMessagingCalls = Array.from(pendingMessagingCalls.values());
						if ((await Promise.all(unresolvedJsonlMessagingCalls.map(isPreparedInternalSourceReply))).some((isInternalSourceReply) => !isInternalSourceReply)) {
							didSendViaMessagingTool = true;
							recordRunError(/* @__PURE__ */ new Error("CLI JSONL message tool call remained unresolved after exit"));
						} else recordRunError(/* @__PURE__ */ new Error("CLI JSONL source reply call remained unresolved after exit"));
					}
					if (gatewayCaptureKey) {
						if (!await waitForMcpLoopbackToolCallCaptureIdle(gatewayCaptureKey, {
							timeoutMs: CLI_MCP_DELIVERY_DRAIN_GRACE_MS,
							admissionGraceMs: CLI_MCP_REQUEST_ADMISSION_GRACE_MS
						})) {
							if (shouldUseClaudeLiveSession(context)) await rotateClaudeLiveMcpCaptureKeyForContext(context);
							const unresolvedPreparedMessagingCalls = Array.from(inFlightPreparedMessagingCalls);
							const internalSourceReplyCount = (await Promise.all(unresolvedPreparedMessagingCalls.map(isPreparedInternalSourceReply))).filter(Boolean).length;
							if (inFlightUnclassifiedMcpRequests > 0 || inFlightMessagingToolCalls > internalSourceReplyCount) {
								didSendViaMessagingTool = true;
								recordRunError(/* @__PURE__ */ new Error("CLI message tool call remained in flight after exit"));
							} else if (inFlightMessagingToolCalls > 0) recordRunError(/* @__PURE__ */ new Error("CLI source reply call remained in flight after exit"));
						}
					}
				} catch (error) {
					if (pendingMessagingCalls.size > 0 || inFlightUnclassifiedMcpRequests > 0 || inFlightMessagingToolCalls > 0) didSendViaMessagingTool = true;
					recordRunError(error);
				} finally {
					if (gatewayCaptureKey) clearMcpLoopbackToolCallCapture(gatewayCaptureKey);
				}
				try {
					await cleanupMcpCaptureAttempt?.();
				} catch (error) {
					recordRunError(error);
				}
				try {
					restoreSkillEnv?.();
				} catch (error) {
					recordRunError(error);
				}
			}
			if (runFailed) throw attachCliMessagingDeliveryEvidence(runError, {
				didSendViaMessagingTool,
				didDeliverSourceReplyViaMessageTool,
				messagingToolSentTexts,
				messagingToolSentMediaUrls,
				messagingToolSentTargets,
				messagingToolSourceReplyPayloads
			});
			if (!runOutput) throw new Error("CLI run completed without output");
			return withExecutionEvidence(runOutput);
		});
		return completedOutput;
	} catch (error) {
		executionError = error;
		throw error;
	} finally {
		if (!fallbackClaudeSkillsPluginCleanupOwned) await cleanupOuterResource(fallbackClaudeSkillsPlugin?.cleanup);
		if (systemPromptFile) await cleanupOuterResource(systemPromptFile.cleanup);
		if (cleanupImages) await cleanupOuterResource(cleanupImages);
	}
}
//#endregion
export { executePreparedCliRun as t };
