import { c as isRecord } from "./record-coerce-DItp3I4t.js";
import { t as findCodeRegions } from "./code-regions-BSt0fAqe.js";
import "./string-coerce-runtime-C8jKEm3h.js";
import "./text-chunking-6CyoCsRp.js";
//#region extensions/anthropic/cli-output.ts
const CLAUDE_RAW_TOOL_OUTPUT_ERROR = "Claude CLI returned malformed tool output (invalid request format): raw tool protocol appeared as assistant text. OpenClaw refused to persist or deliver it.";
const RAW_INVOKE_TAG_RE = /<invoke(?=[ \t>])[^<>\r\n]*>/gu;
const RAW_PARAMETER_TAG_RE = /<parameter(?=[ \t>])[^<>\r\n]*>/gu;
const RAW_INVOKE_CLOSE_TAG_RE = /<\/invoke[ \t]*>/gu;
const RAW_PARAMETER_LOOKAHEAD_CHARS = 2048;
const OBSERVED_TRUNCATED_LEAK_PREFIXES = /* @__PURE__ */ new Set([
	"call",
	"count",
	"court"
]);
function readTagNameAttribute(tag, elementName) {
	const attribute = /[ \t]+([^\s=/>]+)[ \t]*=[ \t]*(?:"([^"]*)"|'([^']*)')/gy;
	const tagEnd = tag.length - 1;
	let cursor = elementName.length + 1;
	while (cursor < tagEnd) {
		attribute.lastIndex = cursor;
		const match = attribute.exec(tag);
		if (!match) return "";
		if (match[1] === "name") return match[2] ?? match[3] ?? "";
		cursor = attribute.lastIndex;
	}
	return "";
}
function isStandaloneLineTag(text, index) {
	const lineStart = text.lastIndexOf("\n", index - 1) + 1;
	return /^[ ]{0,3}$/u.test(text.slice(lineStart, index));
}
function isStandaloneOpeningTagLine(text, index, tagLength) {
	if (!isStandaloneLineTag(text, index)) return false;
	const lineEnd = text.indexOf("\n", index + tagLength);
	const trailingText = text.slice(index + tagLength, lineEnd === -1 ? text.length : lineEnd);
	return /^[ \t]*\r?$/u.test(trailingText);
}
function isInsideCodeRegion(index, regions) {
	let low = 0;
	let high = regions.length - 1;
	while (low <= high) {
		const middle = Math.floor((low + high) / 2);
		const region = regions[middle];
		if (!region) return false;
		if (index < region.start) high = middle - 1;
		else if (index >= region.end) low = middle + 1;
		else return true;
	}
	return false;
}
function hasObservedTruncatedLeakPrefix(text, index, toolName) {
	const previousNonEmptyLine = text.slice(0, index).split(/\r?\n/gu).findLast((line) => line.trim().length > 0)?.trim();
	return previousNonEmptyLine === toolName || previousNonEmptyLine !== void 0 && OBSERVED_TRUNCATED_LEAK_PREFIXES.has(previousNonEmptyLine);
}
function findNextStandaloneTag(text, index, regions, pattern) {
	const scanner = new RegExp(pattern.source, pattern.flags);
	scanner.lastIndex = index;
	for (let match = scanner.exec(text); match; match = scanner.exec(text)) if (isStandaloneOpeningTagLine(text, match.index, match[0].length) && !isInsideCodeRegion(match.index, regions)) return match.index;
	return null;
}
/** Detect Claude's legacy tool protocol only when it occupies standalone assistant lines. */
function hasClaudeRawToolInvocation(text) {
	if (!text.includes("<invoke") || !text.includes("<parameter")) return false;
	const codeRegions = findCodeRegions(text);
	RAW_INVOKE_TAG_RE.lastIndex = 0;
	for (const match of text.matchAll(RAW_INVOKE_TAG_RE)) {
		const index = match.index;
		const toolName = readTagNameAttribute(match[0], "invoke");
		if (!/^[A-Z]/u.test(toolName) && !toolName.startsWith("mcp__") || !isStandaloneOpeningTagLine(text, index, match[0].length) || isInsideCodeRegion(index, codeRegions)) continue;
		const invocationBodyStart = index + match[0].length;
		const invokeCloseIndex = findNextStandaloneTag(text, invocationBodyStart, codeRegions, RAW_INVOKE_CLOSE_TAG_RE);
		const nextInvokeIndex = findNextStandaloneTag(text, invocationBodyStart, codeRegions, RAW_INVOKE_TAG_RE);
		const completeInvokeCloseIndex = invokeCloseIndex !== null && (nextInvokeIndex === null || invokeCloseIndex < nextInvokeIndex) ? invokeCloseIndex : null;
		const parameterSearchEnd = Math.min(text.length, invocationBodyStart + RAW_PARAMETER_LOOKAHEAD_CHARS, completeInvokeCloseIndex ?? text.length, nextInvokeIndex ?? text.length);
		const parameterText = text.slice(invocationBodyStart, parameterSearchEnd);
		let parameterIndex = null;
		for (const parameterMatch of parameterText.matchAll(RAW_PARAMETER_TAG_RE)) {
			const candidateIndex = invocationBodyStart + parameterMatch.index;
			if (readTagNameAttribute(parameterMatch[0], "parameter") && isStandaloneLineTag(text, candidateIndex) && !isInsideCodeRegion(candidateIndex, codeRegions)) {
				parameterIndex = candidateIndex;
				break;
			}
		}
		if (parameterIndex === null) continue;
		if (completeInvokeCloseIndex !== null || completeInvokeCloseIndex === null && hasObservedTruncatedLeakPrefix(text, index, toolName)) return true;
	}
	return false;
}
/** Reject malformed terminal Claude results before the generic CLI runner accepts them as prose. */
const parseClaudeCliJsonlEvent = (line) => {
	if (!((line.includes("<invoke") || line.includes("\\u003cinvoke") || line.includes("\\u003Cinvoke")) && (line.includes("<parameter") || line.includes("\\u003cparameter") || line.includes("\\u003Cparameter")))) return null;
	let parsed;
	try {
		parsed = JSON.parse(line);
	} catch {
		return null;
	}
	if (!isRecord(parsed) || parsed.type !== "result" || typeof parsed.result !== "string" || !hasClaudeRawToolInvocation(parsed.result)) return null;
	return {
		kind: "result",
		errorText: CLAUDE_RAW_TOOL_OUTPUT_ERROR
	};
};
//#endregion
export { parseClaudeCliJsonlEvent as t };
