export function parseThreadSuiteSynthesisJson(raw, evidencePaths = []) {
    const parsed = JSON.parse(extractJsonObject(raw));
    return validateThreadSuiteSynthesis(parsed, evidencePaths);
}
export function validateThreadSuiteSynthesis(value, evidencePaths = []) {
    const evidenceSet = new Set(evidencePaths);
    return {
        projectPurpose: requiredString(value.projectPurpose, "projectPurpose"),
        productSummary: requiredString(value.productSummary, "productSummary"),
        architecture: {
            style: requiredString(value.architecture?.style, "architecture.style"),
            components: arrayOf(value.architecture?.components, (item) => normalizeComponent(item, evidenceSet)),
            dataFlow: stringArray(value.architecture?.dataFlow),
            controlFlow: stringArray(value.architecture?.controlFlow),
        },
        commands: arrayOf(value.commands, (item) => normalizeCommand(item, evidenceSet)),
        entrypoints: arrayOf(value.entrypoints, (item) => normalizeEntrypoint(item, evidenceSet)),
        importantFiles: arrayOf(value.importantFiles, normalizeImportantFile),
        domainConcepts: stringArray(value.domainConcepts),
        risks: arrayOf(value.risks, (item) => normalizeRisk(item, evidenceSet)),
        unknowns: arrayOf(value.unknowns, normalizeUnknown),
        recommendations: stringArray(value.recommendations),
        adrCandidates: arrayOf(value.adrCandidates, (item) => normalizeAdrCandidate(item, evidenceSet)),
        memoryCapsules: arrayOf(value.memoryCapsules, (item) => normalizeMemoryCapsule(item, evidenceSet)),
        projectMap: normalizeProjectMap(value.projectMap, value, evidenceSet),
        retrievalRoutes: arrayOf(value.retrievalRoutes, (item) => normalizeRetrievalRoute(item, evidenceSet)),
        riskRegister: normalizeRiskRegister(value.riskRegister, value, evidenceSet),
        agentPolicy: normalizeAgentPolicy(value.agentPolicy),
    };
}
function extractJsonObject(raw) {
    const start = raw.indexOf("{");
    const end = raw.lastIndexOf("}");
    if (start < 0 || end <= start)
        throw new Error("ThreadSuite synthesis did not contain a JSON object");
    return raw.slice(start, end + 1);
}
function requiredString(value, field) {
    if (typeof value !== "string" || value.trim() === "")
        throw new Error(`ThreadSuite synthesis missing ${field}`);
    return truncate(value.trim(), 4000);
}
function optionalString(value) {
    return typeof value === "string" ? truncate(value.trim(), 4000) : "";
}
function stringArray(value) {
    return Array.isArray(value)
        ? value.flatMap((item) => (typeof item === "string" && item.trim() ? [truncate(item.trim(), 1000)] : []))
        : [];
}
function evidenceArray(value, evidenceSet) {
    const evidence = stringArray(value);
    return evidenceSet.size === 0 ? evidence : evidence.filter((path) => evidenceSet.has(path));
}
function arrayOf(value, normalize) {
    return Array.isArray(value) ? value.flatMap((item) => normalize(item) ?? []) : [];
}
function normalizeComponent(item, evidenceSet) {
    if (!isRecord(item))
        return undefined;
    const name = optionalString(item.name);
    if (!name)
        return undefined;
    return {
        name,
        responsibility: optionalString(item.responsibility),
        evidence: evidenceArray(item.evidence, evidenceSet),
    };
}
function normalizeCommand(item, evidenceSet) {
    if (!isRecord(item))
        return undefined;
    const command = optionalString(item.command);
    if (!command)
        return undefined;
    return {
        command,
        purpose: optionalString(item.purpose),
        confidence: confidence(item.confidence),
        evidence: evidenceArray(item.evidence, evidenceSet),
    };
}
function normalizeEntrypoint(item, evidenceSet) {
    if (!isRecord(item))
        return undefined;
    const path = optionalString(item.path);
    if (!path)
        return undefined;
    return { path, role: optionalString(item.role), evidence: evidenceArray(item.evidence, evidenceSet) };
}
function normalizeImportantFile(item) {
    if (!isRecord(item))
        return undefined;
    const path = optionalString(item.path);
    if (!path)
        return undefined;
    return { path, why: optionalString(item.why) };
}
function normalizeRisk(item, evidenceSet) {
    if (!isRecord(item))
        return undefined;
    const risk = optionalString(item.risk);
    if (!risk)
        return undefined;
    return { risk, reason: optionalString(item.reason), evidence: evidenceArray(item.evidence, evidenceSet) };
}
function normalizeUnknown(item) {
    if (!isRecord(item))
        return undefined;
    const question = optionalString(item.question);
    if (!question)
        return undefined;
    return { question, missingEvidence: optionalString(item.missingEvidence) };
}
function normalizeAdrCandidate(item, evidenceSet) {
    if (!isRecord(item))
        return undefined;
    const title = optionalString(item.title);
    if (!title)
        return undefined;
    return {
        title,
        context: optionalString(item.context),
        decision: optionalString(item.decision),
        consequences: optionalString(item.consequences),
        evidence: evidenceArray(item.evidence, evidenceSet),
    };
}
function normalizeMemoryCapsule(item, evidenceSet) {
    if (!isRecord(item))
        return undefined;
    const category = optionalString(item.category);
    const summary = optionalString(item.summary);
    if (!category || !summary)
        return undefined;
    return {
        category,
        summary,
        content: optionalString(item.content),
        evidence: evidenceArray(item.evidence, evidenceSet),
    };
}
function normalizeProjectMap(projectMap, fallback, evidenceSet) {
    const record = isRecord(projectMap) ? projectMap : {};
    const fallbackComponents = arrayOf(fallback.architecture?.components, (item) => normalizeProjectMapComponent(item, evidenceSet));
    const fallbackEntrypoints = arrayOf(fallback.entrypoints, (item) => normalizeProjectMapEntrypoint(item, evidenceSet));
    const fallbackCoreFiles = arrayOf(fallback.importantFiles, (item) => normalizeCoreFile(item, evidenceSet));
    return {
        components: arrayOf(record.components, (item) => normalizeProjectMapComponent(item, evidenceSet, true)).concat(fallbackComponents),
        entrypoints: arrayOf(record.entrypoints, (item) => normalizeProjectMapEntrypoint(item, evidenceSet)).concat(fallbackEntrypoints),
        coreFiles: arrayOf(record.coreFiles, (item) => normalizeCoreFile(item, evidenceSet)).concat(fallbackCoreFiles),
    };
}
function normalizeProjectMapComponent(item, evidenceSet, includeDepends = false) {
    if (!isRecord(item))
        return undefined;
    const name = optionalString(item.name);
    if (!name)
        return undefined;
    return {
        name,
        responsibility: optionalString(item.responsibility),
        dependsOn: includeDepends ? stringArray(item.dependsOn) : [],
        files: filterKnownPaths(stringArray(item.files), evidenceSet),
        evidence: evidenceArray(item.evidence, evidenceSet),
        confidence: confidence(item.confidence),
    };
}
function normalizeProjectMapEntrypoint(item, evidenceSet) {
    if (!isRecord(item))
        return undefined;
    const path = optionalString(item.path);
    if (!path)
        return undefined;
    return {
        path,
        role: optionalString(item.role),
        evidence: evidenceArray(item.evidence, evidenceSet),
        confidence: confidence(item.confidence),
    };
}
function normalizeCoreFile(item, evidenceSet) {
    if (!isRecord(item))
        return undefined;
    const path = optionalString(item.path);
    if (!path)
        return undefined;
    return {
        path,
        reason: optionalString(item.reason) || optionalString(item.why),
        evidence: evidenceArray(item.evidence, evidenceSet),
        confidence: confidence(item.confidence),
    };
}
function normalizeRetrievalRoute(item, evidenceSet) {
    if (!isRecord(item))
        return undefined;
    const intent = optionalString(item.intent);
    if (!intent)
        return undefined;
    return {
        intent,
        firstFiles: filterKnownPaths(stringArray(item.firstFiles), evidenceSet),
        queryHints: stringArray(item.queryHints),
        rationale: optionalString(item.rationale),
        evidence: evidenceArray(item.evidence, evidenceSet),
        confidence: confidence(item.confidence),
    };
}
function normalizeRiskRegister(riskRegister, fallback, evidenceSet) {
    const record = isRecord(riskRegister) ? riskRegister : {};
    const fallbackItems = arrayOf(fallback.risks, (item) => normalizeRiskRegisterItem(item, evidenceSet));
    const fallbackQuestions = arrayOf(fallback.unknowns, (item) => normalizeOpenQuestion(item, evidenceSet));
    return {
        items: arrayOf(record.items, (item) => normalizeRiskRegisterItem(item, evidenceSet)).concat(fallbackItems),
        openQuestions: arrayOf(record.openQuestions, (item) => normalizeOpenQuestion(item, evidenceSet)).concat(fallbackQuestions),
    };
}
function normalizeRiskRegisterItem(item, evidenceSet) {
    if (!isRecord(item))
        return undefined;
    const title = optionalString(item.title) || optionalString(item.risk);
    if (!title)
        return undefined;
    return {
        title,
        severity: severity(item.severity),
        reason: optionalString(item.reason),
        evidence: evidenceArray(item.evidence, evidenceSet),
        confidence: confidence(item.confidence),
    };
}
function normalizeOpenQuestion(item, evidenceSet) {
    if (!isRecord(item))
        return undefined;
    const question = optionalString(item.question);
    if (!question)
        return undefined;
    return {
        question,
        whyItMatters: optionalString(item.whyItMatters) || optionalString(item.missingEvidence),
        evidence: evidenceArray(item.evidence, evidenceSet),
    };
}
function normalizeAgentPolicy(agentPolicy) {
    const record = isRecord(agentPolicy) ? agentPolicy : {};
    return {
        safeCommands: stringArray(record.safeCommands),
        expensiveCommands: stringArray(record.expensiveCommands),
        validationExpectations: stringArray(record.validationExpectations),
        conventions: stringArray(record.conventions),
    };
}
function filterKnownPaths(paths, evidenceSet) {
    return evidenceSet.size === 0 ? paths : paths.filter((path) => evidenceSet.has(path));
}
function severity(value) {
    return value === "low" || value === "medium" || value === "high" ? value : "medium";
}
function confidence(value) {
    return value === "low" || value === "medium" || value === "high" ? value : "medium";
}
function isRecord(value) {
    return typeof value === "object" && value !== null;
}
function truncate(value, max) {
    return value.length > max ? value.slice(0, max) : value;
}
//# sourceMappingURL=synthesis-schema.js.map