export const PIXCODE_HANDOFF_PROTOCOL = 'pixcode.handoff.v1';
const VALID_TASK_STATUSES = new Set([
    'ready',
    'completed',
    'blocked',
    'failed',
    'needs-review',
]);
function extractJsonCandidate(text) {
    const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1]?.trim();
    if (fenced)
        return fenced;
    const start = text.indexOf('{');
    const end = text.lastIndexOf('}');
    if (start === -1 || end === -1 || end <= start)
        return null;
    return text.slice(start, end + 1);
}
function readRequiredString(record, key) {
    const value = record[key];
    if (typeof value !== 'string' || !value.trim())
        return null;
    return value.trim();
}
function sanitizeChangedFile(filePath) {
    const normalized = filePath.trim().replaceAll('\\', '/');
    if (!normalized)
        return '';
    if (!normalized.startsWith('/') && !/^[a-zA-Z]:\//.test(normalized))
        return normalized;
    return normalized.split('/').filter(Boolean).slice(-4).join('/');
}
function readStringArray(record, key) {
    const value = record[key];
    if (!Array.isArray(value))
        return null;
    return value
        .filter((item) => typeof item === 'string')
        .map((item) => key === 'changedFiles' ? sanitizeChangedFile(item) : item.trim())
        .filter(Boolean)
        .slice(0, 40);
}
export function parseHandoffArtifact(text, metadata = {}) {
    const candidate = extractJsonCandidate(text);
    if (!candidate) {
        return { ok: false, error: 'Invalid handoff artifact: expected one JSON object.' };
    }
    let parsed;
    try {
        parsed = JSON.parse(candidate);
    }
    catch (error) {
        return {
            ok: false,
            error: `Invalid handoff artifact: JSON parse failed (${error instanceof Error ? error.message : String(error)}).`,
        };
    }
    if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
        return { ok: false, error: 'Invalid handoff artifact: payload must be an object.' };
    }
    const record = parsed;
    if (record.protocol !== PIXCODE_HANDOFF_PROTOCOL) {
        return { ok: false, error: `Invalid handoff artifact: protocol must be ${PIXCODE_HANDOFF_PROTOCOL}.` };
    }
    const taskStatus = record.taskStatus;
    if (typeof taskStatus !== 'string' || !VALID_TASK_STATUSES.has(taskStatus)) {
        return { ok: false, error: 'Invalid handoff artifact: taskStatus is missing or unsupported.' };
    }
    const contextSummary = readRequiredString(record, 'contextSummary');
    const taskResult = readRequiredString(record, 'taskResult');
    const changedFiles = readStringArray(record, 'changedFiles');
    const blockers = readStringArray(record, 'blockers');
    const risks = readStringArray(record, 'risks');
    const nextAction = readRequiredString(record, 'nextAction');
    const nextInstructions = readRequiredString(record, 'nextInstructions');
    if (!contextSummary || !taskResult || !changedFiles || !blockers || !risks || !nextAction || !nextInstructions) {
        return {
            ok: false,
            error: 'Invalid handoff artifact: required fields are protocol, taskStatus, contextSummary, taskResult, changedFiles, blockers, risks, nextAction, and nextInstructions.',
        };
    }
    return {
        ok: true,
        artifact: {
            protocol: PIXCODE_HANDOFF_PROTOCOL,
            taskStatus: taskStatus,
            contextSummary,
            taskResult,
            changedFiles,
            blockers,
            risks,
            nextAction,
            nextInstructions,
            producedBy: {
                workflowRunId: metadata.workflowRunId,
                nodeId: metadata.nodeId,
                agentLabel: metadata.agentLabel,
                stage: metadata.stage,
            },
            createdAt: new Date().toISOString(),
        },
    };
}
export function formatHandoffArtifactForContext(artifact) {
    return [
        `Pixcode handoff artifact (${PIXCODE_HANDOFF_PROTOCOL})`,
        JSON.stringify(artifact, null, 2),
    ].join('\n');
}
export function handoffArtifactToWorkflowArtifact(artifact) {
    return {
        type: 'handoff-artifact',
        data: artifact,
        metadata: {
            protocol: artifact.protocol,
            taskStatus: artifact.taskStatus,
            changedFileCount: artifact.changedFiles.length,
            blockerCount: artifact.blockers.length,
            nextAction: artifact.nextAction,
        },
    };
}
//# sourceMappingURL=handoff-artifact.js.map