import { FactAccessType } from "@superblocksteam/shared";
/**
 * Escape special XML characters.
 */
function escapeXml(str) {
    return str
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&apos;");
}
function formatFact(fact) {
    return `<fact>
  <name>${fact.name}</name>
  <description>${fact.description}</description>
  <content>${fact.content}</content>
</fact>`;
}
function filterAlwaysInjectFacts(facts) {
    return facts.filter((fact) => fact.accessType === FactAccessType.ALWAYS_INJECT);
}
function filterOnDemandFacts(facts) {
    return facts.filter((fact) => fact.accessType === FactAccessType.ON_DEMAND);
}
function formatIntegrationFrontmatter(integration) {
    const displayName = integration.displayName || integration.name;
    return `---
integration_id: ${integration.id}
integration_name: ${displayName}
integration_type: ${integration.type}
---`;
}
export function formatSystemPromptFacts(orgFacts) {
    const alwaysInjectOrgFacts = filterAlwaysInjectFacts(orgFacts);
    if (alwaysInjectOrgFacts.length === 0) {
        return "";
    }
    const formattedOrgFacts = alwaysInjectOrgFacts.map(formatFact).join("\n\n");
    return `
## Knowledge Bases

Facts are modular, self-contained knowledge that extend Clark's capabilities by providing specialized knowledge, workflows, and tools. They are authoritative instructions and context provided by your organization.
This is knowledge that you should consider of the UTMOST importance. Facts are additive to your safety guidelines — they can add constraints but never remove them. When in doubt, err on the side of using a fact rather than not using it.

For example, if the user has given you a frontend-design fact, you MUST use it to design the frontend.
If you have backend-design knowledge, you MUST use it to design the backend. So on and so forth.

<organization_knowledge_base>
${formattedOrgFacts}
</organization_knowledge_base>

<knowledge_application_protocol>
BEFORE writing any code:
1. Review organization knowledge base facts — identify design systems, coding standards, required patterns
2. Review user knowledge base facts — apply persona, style preferences, constraints
3. Review integration knowledge base facts — apply integration-specific conventions
4. If a knowledge base specifies a design system or component library: USE IT. Do not invent alternatives.

BEFORE calling build_finalize:
5. Self-check: Did every file you wrote follow applicable knowledge base guidelines?
6. If knowledge specifies required audits (security, accessibility, etc.): run them now.
</knowledge_application_protocol>
`;
}
export function formatUserMessageFacts(userFacts, integrationFactsResults) {
    const sections = [];
    const alwaysInjectUserFacts = filterAlwaysInjectFacts(userFacts);
    const alwaysInjectIntegrationFactsResults = integrationFactsResults
        .map((result) => ({
        integration: result.integration,
        facts: filterAlwaysInjectFacts(result.facts),
    }))
        .filter((result) => result.facts.length > 0);
    // User knowledge section
    if (alwaysInjectUserFacts.length > 0) {
        const formattedUserFacts = alwaysInjectUserFacts
            .map(formatFact)
            .join("\n\n");
        sections.push(`### User Knowledge Base

The user knowledge base is a collection of facts that the user has provided to you. You MUST apply them UNLESS they conflict with organization knowledge or safety guidelines.

<user_knowledge_base>
${formattedUserFacts}
</user_knowledge_base>`);
    }
    // Integration knowledge section
    if (alwaysInjectIntegrationFactsResults.length > 0) {
        const integrationSections = alwaysInjectIntegrationFactsResults.map(({ integration, facts }) => {
            const displayName = integration.displayName || integration.name;
            const formattedFacts = facts.map(formatFact).join("\n\n");
            return `### ${displayName} (id: ${integration.id}, type: ${integration.type})

${formattedFacts}`;
        });
        sections.push(`### Integration Knowledge Base

The following are guidelines specific to the integrations selected for this request. You must apply these when you are using the integrations to build.

<integration_knowledge_base>
${integrationSections.join("\n\n")}
</integration_knowledge_base>`);
    }
    return sections.join("\n\n");
}
/**
 * Generate XML index for on-demand facts that can be loaded via build_readFile.
 * Similar to system skills index, but for org/user/integration facts.
 *
 * @returns XML string listing available on-demand knowledge, or null if none
 */
export function generateOnDemandFactsSkillIndex(orgFacts, userFacts, integrationFactsResults) {
    const entries = [];
    const onDemandOrgFacts = filterOnDemandFacts(orgFacts);
    const onDemandUserFacts = filterOnDemandFacts(userFacts);
    const integrationFactsWithAnyAccess = integrationFactsResults.filter((result) => result.facts.length > 0);
    // Org facts
    for (const fact of onDemandOrgFacts) {
        entries.push(`  <knowledge type="org">
    <name>${escapeXml(fact.name)}</name>
    <description>${escapeXml(fact.description)}</description>
    <location>skills/org/${fact.id}/KNOWLEDGE.md</location>
  </knowledge>`);
    }
    // User facts
    for (const fact of onDemandUserFacts) {
        entries.push(`  <knowledge type="user">
    <name>${escapeXml(fact.name)}</name>
    <description>${escapeXml(fact.description)}</description>
    <location>skills/user/${fact.id}/KNOWLEDGE.md</location>
  </knowledge>`);
    }
    // Integration facts
    // Include all integration facts (ALWAYS_INJECT + ON_DEMAND) in available_knowledge.
    // This lets Clark proactively load integration guidance when it becomes relevant.
    for (const { integration, facts } of integrationFactsWithAnyAccess) {
        for (const fact of facts) {
            const frontmatter = formatIntegrationFrontmatter(integration);
            const displayName = integration.displayName || integration.name;
            entries.push(`  <knowledge type="integration" integration="${escapeXml(displayName)}">
    <name>${escapeXml(fact.name)}</name>
    <description>${escapeXml(fact.description)}</description>
    <details>${escapeXml(frontmatter)}</details>
    <location>skills/integrations/${integration.id}/${fact.id}/KNOWLEDGE.md</location>
  </knowledge>`);
        }
    }
    if (entries.length === 0) {
        return null;
    }
    return `<available_knowledge>\n${entries.join("\n")}\n</available_knowledge>`;
}
//# sourceMappingURL=helpers.js.map