/**
 * Segment sorted log entries into wake cycles, then classify them
 * as clean, interrupted, or incomplete.
 */
import { WakeCycle } from "./types.js";
/**
 * Walk sorted entries, group into wake→(next wake) cycles.
 *
 * A cycle starts at each `wake` entry and extends to the entry before the
 * next `wake` entry (or end of input).  Multiple `result` entries can appear
 * within one cycle when session switches occur — only the final `result` is
 * treated as the cycle completion marker.
 */
export function segmentWakeCycles(entries) {
    const cycles = [];
    let current;
    for (const entry of entries) {
        if (entry.category === "wake") {
            if (current) {
                cycles.push(current);
            }
            current = new WakeCycle();
            current.entries.push(entry);
            continue;
        }
        if (!current)
            continue;
        current.entries.push(entry);
        if (entry.category === "incoming" &&
            entry.message.includes("[interrupt]")) {
            current.hasInterrupts = true;
        }
        if (entry.category === "result") {
            current.hasResult = true;
        }
    }
    if (current) {
        cycles.push(current);
    }
    return cycles;
}
/**
 * Split cycles into clean, interrupted, and incomplete buckets.
 */
export function classifyCycles(cycles) {
    const clean = [];
    const interrupted = [];
    const incomplete = [];
    for (const c of cycles) {
        if (c.hasInterrupts) {
            interrupted.push(c);
        }
        else if (!c.hasResult) {
            incomplete.push(c);
        }
        else {
            // Hidden interrupt: incoming after model output started
            let sawModel = false;
            let hasHiddenInterrupt = false;
            for (const e of c.entries) {
                if (e.category === "assistant" || e.category === "tool_call") {
                    sawModel = true;
                }
                else if (e.category === "incoming" && sawModel) {
                    hasHiddenInterrupt = true;
                    break;
                }
            }
            if (hasHiddenInterrupt) {
                c.hasInterrupts = true;
                interrupted.push(c);
            }
            else {
                clean.push(c);
            }
        }
    }
    return { clean, interrupted, incomplete };
}
//# sourceMappingURL=segmenter.js.map