/**
 * @internal
 * consistency/parse-progress.mjs — normalize build-progress.json (C15).
 *
 * Accepts any of:
 *   - {completed_subtasks: [{id, completed_at, ...}], pending_subtasks: [id|{id}]}
 *     — canonical shape written by `completeSubtask` in build-progress-sync.mjs;
 *     presence in `completed_subtasks` implies status="completed".
 *     `constituent_ids` entries expand into individual ids so consolidated
 *     entries like "E1+E2" count both E1 and E2 as completed.
 *   - {subtasks: [{id, status}]}              — legacy array shape
 *   - {subtasks: {<id>: {status}}}            — legacy map shape
 *   - {progress: {<id>: {status}}}            — legacy alternate-key map shape
 *
 * Output: {subtasks: Record<string, {status: string}>}
 *
 * Tolerant of missing / empty input — returns `{subtasks: {}}`.
 */
/**
 * @param {object | null | undefined} progress
 */
export function parseBuildProgress(progress) {
    if (!progress || typeof progress !== 'object') {
        return { subtasks: {} };
    }
    const out = {};
    const sub = progress.subtasks;
    if (Array.isArray(sub)) {
        for (const s of sub) {
            if (!s || typeof s !== 'object')
                continue;
            const id = typeof s.id === 'string' ? s.id : s.id != null ? String(s.id) : '';
            if (!id)
                continue;
            out[id] = { status: typeof s.status === 'string' ? s.status : 'unknown' };
        }
    }
    else if (sub && typeof sub === 'object') {
        for (const [id, value] of Object.entries(sub)) {
            if (!value || typeof value !== 'object')
                continue;
            out[id] = { status: typeof value.status === 'string' ? value.status : 'unknown' };
        }
    }
    const prog = progress.progress;
    if (prog && typeof prog === 'object' && !Array.isArray(prog)) {
        for (const [id, value] of Object.entries(prog)) {
            if (out[id])
                continue;
            if (!value || typeof value !== 'object')
                continue;
            out[id] = { status: typeof value.status === 'string' ? value.status : 'unknown' };
        }
    }
    // Canonical shape: completed_subtasks[] — presence implies completed.
    // Also expand `constituent_ids` so consolidated entries (e.g. "E1+E2")
    // count each constituent id as completed.
    const completed = progress.completed_subtasks;
    if (Array.isArray(completed)) {
        for (const entry of completed) {
            if (!entry || typeof entry !== 'object')
                continue;
            const rawId = typeof entry.id === 'string' ? entry.id : entry.id != null ? String(entry.id) : '';
            if (rawId && !out[rawId]) {
                out[rawId] = { status: 'completed' };
            }
            const constituents = Array.isArray(entry.constituent_ids) ? entry.constituent_ids : [];
            for (const cid of constituents) {
                const id = typeof cid === 'string' ? cid : cid != null ? String(cid) : '';
                if (!id)
                    continue;
                if (!out[id])
                    out[id] = { status: 'completed' };
            }
        }
    }
    // Canonical shape: pending_subtasks[] — ids present but not yet complete.
    // Don't overwrite a prior `completed` status if both lists disagree.
    const pending = progress.pending_subtasks;
    if (Array.isArray(pending)) {
        for (const entry of pending) {
            let id = '';
            if (typeof entry === 'string') {
                id = entry;
            }
            else if (entry && typeof entry === 'object' && entry.id != null) {
                id = typeof entry.id === 'string' ? entry.id : String(entry.id);
            }
            if (!id)
                continue;
            if (!out[id])
                out[id] = { status: 'pending' };
        }
    }
    return { subtasks: out };
}
//# sourceMappingURL=parse-progress.mjs.map