/**
 * Parser for Claude Agent SDK transcript JSONL.
 *
 * Schema (one JSON object per line):
 *   { type: "user" | "assistant", message: { role, content: [...] }, ... }
 *
 * `content` blocks of interest:
 *   - { type: "text", text }
 *   - { type: "tool_use", name, input }
 *   - { type: "tool_result", tool_use_id, content, is_error }
 *   - { type: "image" | "image_url", ... }   (stripped)
 *
 * Lines with `isMeta: true` or `type: "system"` are skipped — they're SDK
 * housekeeping records that don't contribute to the summary.
 */
import { isTrivialToolName } from "./trivial-tools.js";
import { sanitizeForSummary } from "./sanitize.js";
function parseLines(lines) {
    const entries = [];
    for (const line of lines) {
        if (!line.trim())
            continue;
        try {
            const parsed = JSON.parse(line);
            const type = parsed.type;
            const isMeta = parsed.isMeta === true;
            const subtype = parsed.subtype;
            if (isMeta)
                continue;
            if (type === "system") {
                if (subtype === "compact_boundary")
                    continue;
                continue;
            }
            if (type === "assistant") {
                const message = parsed.message;
                if (message?.content && Array.isArray(message.content)) {
                    for (const block of message.content) {
                        const b = block;
                        if (b.type === "text" && typeof b.text === "string") {
                            entries.push({ type: "assistant_text", text: b.text });
                        }
                        else if (b.type === "tool_use") {
                            const sanitizedInput = sanitizeForSummary(b.input);
                            const inputStr = sanitizedInput ? JSON.stringify(sanitizedInput) : "";
                            const truncated = inputStr.length > 500
                                ? inputStr.slice(0, 500) + "...[truncated]"
                                : inputStr;
                            entries.push({
                                type: "tool_call",
                                toolName: b.name,
                                toolInput: truncated,
                            });
                        }
                    }
                }
            }
            else if (type === "user") {
                const message = parsed.message;
                if (message?.content) {
                    if (typeof message.content === "string") {
                        entries.push({ type: "user_message", text: message.content });
                    }
                    else if (Array.isArray(message.content)) {
                        for (const block of message.content) {
                            const b = block;
                            if (b.type === "text" && typeof b.text === "string") {
                                entries.push({ type: "user_message", text: b.text });
                            }
                            else if (b.type === "image" || b.type === "image_url") {
                                entries.push({ type: "user_message", text: "[Image omitted]" });
                            }
                            else if (b.type === "tool_result") {
                                const content = b.content;
                                const raw = typeof content === "string"
                                    ? content
                                    : JSON.stringify(sanitizeForSummary(content));
                                const truncated = raw.length > 300
                                    ? raw.slice(0, 300) + "...[truncated]"
                                    : raw;
                                entries.push({
                                    type: "tool_result",
                                    toolName: b.tool_use_id ?? "unknown",
                                    text: truncated,
                                    isError: b.is_error === true,
                                });
                            }
                        }
                    }
                }
            }
        }
        catch {
            // Skip malformed lines
        }
    }
    return entries;
}
function renderEntries(entries) {
    const parts = [];
    for (const entry of entries) {
        switch (entry.type) {
            case "user_message":
                parts.push(`[User] ${entry.text ?? ""}`);
                break;
            case "assistant_text":
                parts.push(`[Assistant] ${entry.text ?? ""}`);
                break;
            case "tool_call":
                parts.push(`[Tool Call] ${entry.toolName ?? "unknown"}(${entry.toolInput ?? ""})`);
                break;
            case "tool_result":
                // Only error results are informative for summary; success results are
                // usually large and noisy, so we drop them.
                if (entry.isError) {
                    parts.push(`[Tool Error] ${entry.text ?? ""}`);
                }
                break;
        }
    }
    return parts.join("\n");
}
const MAX_TOOL_CALLS_PER_CYCLE = 500;
const TOOLS_WITH_ACTION_ARG = new Set([
    "manage_email", "manage_calendar", "manage_drive",
    "manage_totp", "manage_skills", "manage_mcp_servers",
    "memory", "stock_data",
]);
function isTimestampWithinCycle(timestamp, context) {
    return timestamp >= context.cycleStartedAt && timestamp <= context.cycleEndedAt;
}
export const claudeTranscriptParser = {
    kind: "claude",
    parseForSummary(lines) {
        return renderEntries(parseLines(lines));
    },
    isOnlyTrivialToolCalls(lines) {
        let hasToolCalls = false;
        for (const line of lines) {
            if (!line.trim())
                continue;
            try {
                const parsed = JSON.parse(line);
                if (parsed.type !== "assistant")
                    continue;
                const message = parsed.message;
                if (!message?.content || !Array.isArray(message.content))
                    continue;
                for (const block of message.content) {
                    const b = block;
                    if (b.type !== "tool_use")
                        continue;
                    hasToolCalls = true;
                    const toolName = b.name;
                    if (!toolName || !isTrivialToolName(toolName)) {
                        return false;
                    }
                }
            }
            catch {
                // Skip malformed lines
            }
        }
        return hasToolCalls;
    },
    extractToolCalls(lines, context) {
        const inFlight = new Map();
        const completed = [];
        let currentTimestamp = context.cycleStartedAt;
        for (const line of lines) {
            if (!line.trim())
                continue;
            try {
                const parsed = JSON.parse(line);
                const type = parsed.type;
                if (parsed.isMeta === true)
                    continue;
                if (typeof parsed.timestamp === "string") {
                    currentTimestamp = parsed.timestamp;
                }
                if (type === "assistant") {
                    const message = parsed.message;
                    const parentToolUseIdRaw = parsed.parent_tool_use_id;
                    const parentToolUseId = typeof parentToolUseIdRaw === "string" && parentToolUseIdRaw.length > 0
                        ? parentToolUseIdRaw
                        : undefined;
                    if (message?.content && Array.isArray(message.content)) {
                        for (const block of message.content) {
                            const b = block;
                            if (b.type === "tool_use") {
                                const toolUseId = b.id ??
                                    b.tool_use_id;
                                const toolName = b.name;
                                if (toolUseId && toolName && isTimestampWithinCycle(currentTimestamp, context)) {
                                    let action;
                                    const strippedName = toolName.replace(/^mcp__visionclaw__/, "").replace(/^mcp__playwright__/, "");
                                    if (TOOLS_WITH_ACTION_ARG.has(strippedName)) {
                                        const input = (b.input ?? b.arguments);
                                        const rawAction = input?.action ?? input?.command;
                                        if (typeof rawAction === "string")
                                            action = rawAction;
                                    }
                                    inFlight.set(toolUseId, { toolUseId, toolName, parentToolUseId, startedAt: currentTimestamp, action });
                                }
                            }
                        }
                    }
                }
                else if (type === "user") {
                    const message = parsed.message;
                    if (message?.content && Array.isArray(message.content)) {
                        for (const block of message.content) {
                            const b = block;
                            if (b.type === "tool_result") {
                                const toolUseId = b.tool_use_id;
                                if (!toolUseId)
                                    continue;
                                const pending = inFlight.get(toolUseId);
                                if (!pending)
                                    continue;
                                inFlight.delete(toolUseId);
                                const isError = b.is_error === true;
                                completed.push({
                                    toolName: pending.toolName,
                                    toolUseId: pending.toolUseId,
                                    parentToolUseId: pending.parentToolUseId,
                                    startedAt: pending.startedAt,
                                    endedAt: currentTimestamp,
                                    success: !isError,
                                    ...(isError ? { errorKind: "tool_error" } : {}),
                                    ...(pending.action ? { action: pending.action } : {}),
                                });
                            }
                        }
                    }
                }
            }
            catch {
                // Skip malformed lines
            }
        }
        for (const pending of inFlight.values()) {
            completed.push({
                toolName: pending.toolName,
                toolUseId: pending.toolUseId,
                parentToolUseId: pending.parentToolUseId,
                startedAt: pending.startedAt,
                endedAt: context.cycleEndedAt,
                success: false,
                errorKind: "missing_tool_result",
                ...(pending.action ? { action: pending.action } : {}),
            });
        }
        completed.sort((a, b) => a.startedAt.localeCompare(b.startedAt));
        const originalCount = completed.length;
        const truncated = originalCount > MAX_TOOL_CALLS_PER_CYCLE;
        const toolCalls = truncated ? completed.slice(0, MAX_TOOL_CALLS_PER_CYCLE) : completed;
        return {
            toolCalls,
            toolCallCount: originalCount,
            truncated,
            reportedToolCallCount: truncated ? toolCalls.length : null,
        };
    },
};
//# sourceMappingURL=claude-parser.js.map