"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveConcreteBackendStackSelection = resolveConcreteBackendStackSelection;
exports.buildArchitectureProposal = buildArchitectureProposal;
const stackAdapters_1 = require("../stackAdapters");
const implementationProfileResolution_1 = require("./implementationProfileResolution");
function addEvidence(evidence, value) {
    if (!evidence.includes(value)) {
        evidence.push(value);
    }
}
function uniqueSorted(values) {
    return [...new Set(values)].sort((left, right) => left.localeCompare(right));
}
function uniqueLimited(values, limit = 5) {
    return uniqueSorted(values.filter((value) => value.trim().length > 0)).slice(0, limit);
}
function uniqueInOrder(values) {
    const seen = new Set();
    const result = [];
    for (const value of values) {
        if (seen.has(value)) {
            continue;
        }
        seen.add(value);
        result.push(value);
    }
    return result;
}
function uniqueSortedKinds(values) {
    return [...new Set(values)].sort((left, right) => left.localeCompare(right));
}
function sortModuleCandidates(candidates) {
    return [...candidates].sort((left, right) => {
        const classificationCompare = left.classification.localeCompare(right.classification);
        if (classificationCompare !== 0) {
            return classificationCompare;
        }
        return left.name.localeCompare(right.name);
    });
}
function normalizeIdentity(value) {
    return value
        .toLowerCase()
        .replace(/[^a-z0-9]+/gu, '');
}
function normalizeComponentPath(value) {
    return value.replaceAll('\\', '/').replace(/\/+$/gu, '');
}
function isComponentAlignedModuleCandidate(candidate, components, resources = []) {
    const candidatePath = normalizeComponentPath(candidate.path);
    const candidateNameIdentity = normalizeIdentity(candidate.name);
    const candidatePathLeafIdentity = normalizeIdentity(candidatePath.split('/').filter((segment) => segment.length > 0).at(-1) ?? candidate.path);
    const matchesComponent = components.some((component) => {
        const componentPath = normalizeComponentPath(component.path);
        if (componentPath.length > 0 &&
            componentPath !== '.' &&
            (componentPath === candidatePath ||
                componentPath.startsWith(`${candidatePath}/`) ||
                candidatePath.startsWith(`${componentPath}/`))) {
            return true;
        }
        const componentIdentities = [
            component.id,
            component.name,
            componentPath.split('/').filter((segment) => segment.length > 0).at(-1) ?? '',
        ].map(normalizeIdentity);
        return (candidateNameIdentity.length > 0 &&
            componentIdentities.some((identity) => identity.length > 0 && (identity === candidateNameIdentity || identity === candidatePathLeafIdentity)));
    });
    if (matchesComponent) {
        return true;
    }
    return resources.some((resource) => {
        const resourcePath = typeof resource.path === 'string' ? normalizeComponentPath(resource.path) : '';
        if (resourcePath.length > 0 &&
            resourcePath !== '.' &&
            (resourcePath === candidatePath ||
                resourcePath.startsWith(`${candidatePath}/`) ||
                candidatePath.startsWith(`${resourcePath}/`))) {
            return true;
        }
        const resourceIdentities = [
            resource.id ?? '',
            resource.name ?? '',
            resource.provider ?? '',
            resourcePath.split('/').filter((segment) => segment.length > 0).at(-1) ?? '',
        ].map(normalizeIdentity);
        return (candidateNameIdentity.length > 0 &&
            resourceIdentities.some((identity) => identity.length > 0 && (identity === candidateNameIdentity || identity === candidatePathLeafIdentity)));
    });
}
function findSupportOwnerComponent(candidate, components) {
    const candidatePath = normalizeComponentPath(candidate.path);
    return components
        .filter((component) => component.selectedByDefault === false || component.governanceRole === 'support')
        .find((component) => {
        const componentPath = normalizeComponentPath(component.path);
        return componentPath.length > 0 &&
            componentPath !== '.' &&
            (candidatePath === componentPath || candidatePath.startsWith(`${componentPath}/`));
    });
}
function resolveModuleCandidates(detection, resources = []) {
    return sortModuleCandidates((detection.modules?.modules ?? []).map((module) => {
        const isComponentOrResourceAligned = isComponentAlignedModuleCandidate(module, detection.detectedComponents ?? [], resources);
        const supportOwner = findSupportOwnerComponent(module, detection.detectedComponents ?? []);
        const isSupportOwned = Boolean(supportOwner);
        return {
            name: module.name,
            path: module.path,
            classification: (isComponentOrResourceAligned || isSupportOwned) && module.classification === 'architecture-module'
                ? 'uncertain'
                : module.classification,
            confidence: isSupportOwned && module.confidence === 'high' ? 'medium' : module.confidence,
            evidence: [
                ...module.evidence,
                ...(isComponentOrResourceAligned
                    ? ['Matches detected component/service/app or resource identity; review before governing as a module']
                    : []),
                ...(supportOwner
                    ? [`Located under support/tooling component ${supportOwner.path}; available for manual inclusion`]
                    : []),
            ],
            selectedByDefault: (isComponentOrResourceAligned || isSupportOwned) && module.classification === 'architecture-module'
                ? false
                : module.selectedByDefault,
        };
    }));
}
function groupModuleCandidates(candidates) {
    if (candidates.length === 0) {
        return undefined;
    }
    return {
        'architecture-module': candidates.filter((candidate) => candidate.classification === 'architecture-module'),
        'technical-layer': candidates.filter((candidate) => candidate.classification === 'technical-layer'),
        'shared-infrastructure': candidates.filter((candidate) => candidate.classification === 'shared-infrastructure'),
        uncertain: candidates.filter((candidate) => candidate.classification === 'uncertain'),
    };
}
function isProposalProjectKind(value) {
    return value === 'backend' || value === 'frontend' || value === 'library';
}
function getSelectedCandidate(detection) {
    return detection.stacks.candidates?.find((candidate) => candidate.adapterId === detection.stacks.selectedAdapterId);
}
function getBackendComponents(detection) {
    return (detection.detectedComponents ?? [])
        .filter((component) => component.kind === 'backend' || component.kind === 'worker');
}
function getDefaultGovernedBackendComponents(detection) {
    const components = detection.detectedComponents ?? [];
    return components
        .filter((component) => component.kind === 'backend' || component.kind === 'worker')
        .filter((component) => isDefaultGovernedComponent(component, components));
}
function getFrontendComponents(detection) {
    return (detection.detectedComponents ?? [])
        .filter((component) => component.kind === 'frontend');
}
function getLibraryComponents(detection) {
    return (detection.detectedComponents ?? [])
        .filter((component) => component.kind === 'library');
}
function getDataComponents(detection) {
    return (detection.detectedComponents ?? [])
        .filter((component) => component.kind === 'data');
}
function isArchitectureComponentKind(kind) {
    return kind === 'backend' ||
        kind === 'frontend' ||
        kind === 'worker' ||
        kind === 'library' ||
        kind === 'infrastructure' ||
        kind === 'data';
}
function componentEvidenceText(component) {
    return [
        component.name,
        component.path,
        ...(component.governanceEvidence ?? []),
    ].join(' ').toLowerCase();
}
function isCliSupportCandidate(component, allComponents) {
    const text = componentEvidenceText(component);
    if (!/\b(project kind cli|cli\/tooling project kind|bin|commander|yargs|ts-morph|schematics|scaffold|generator)\b/u.test(text)) {
        return false;
    }
    const hasRuntimePeer = allComponents.some((peer) => {
        if (peer.path === component.path || peer.selectedByDefault === false) {
            return false;
        }
        return peer.kind === 'backend' ||
            peer.kind === 'frontend' ||
            peer.kind === 'worker' ||
            Boolean(peer.apiStyle && peer.apiStyle !== 'none' && peer.apiStyle !== 'unknown');
    });
    return hasRuntimePeer;
}
function hasIndependentRuntimeEvidence(component) {
    const text = componentEvidenceText(component);
    return component.governanceRole === 'runtime' && (/Maven executable application evidence/iu.test(text) ||
        /Maven deployable WAR artifact/iu.test(text) ||
        /Published package surface signal/iu.test(text) && !/Path contains support\/tooling role tokens/iu.test(text));
}
function hasSupportRoleEvidence(component) {
    const text = componentEvidenceText(component);
    return /Path contains support\/tooling role tokens|Package metadata describes test\/support usage|Package scripts include development\/test\/support workflows|Private package without runtime publish surface/iu.test(text);
}
function isDefaultGovernedComponent(component, allComponents) {
    if (component.selectedByDefault === false || component.governanceRole === 'support') {
        return false;
    }
    const componentPath = normalizeComponentPath(component.path);
    const supportParent = allComponents.some((peer) => {
        if (peer.path === component.path || !(peer.selectedByDefault === false || peer.governanceRole === 'support')) {
            return false;
        }
        const peerPath = normalizeComponentPath(peer.path);
        return peerPath.length > 0 && peerPath !== '.' && componentPath.startsWith(`${peerPath}/`);
    });
    if (supportParent && !hasIndependentRuntimeEvidence(component)) {
        return false;
    }
    if (isCliSupportCandidate(component, allComponents)) {
        return false;
    }
    return true;
}
function toComponentProjectKind(kind) {
    if (kind === 'backend' || kind === 'worker') {
        return 'backend';
    }
    if (kind === 'frontend') {
        return 'frontend';
    }
    if (kind === 'library') {
        return 'library';
    }
    return undefined;
}
function toComponentType(kind) {
    switch (kind) {
        case 'frontend':
            return 'frontend_app';
        case 'backend':
            return 'backend_service';
        case 'worker':
            return 'worker';
        case 'library':
            return 'library';
        case 'infrastructure':
            return 'infrastructure';
        case 'data':
            return 'data';
        default:
            return 'component';
    }
}
function toComponentStacks(component) {
    if (!component.stack) {
        return undefined;
    }
    if (component.kind === 'backend' || component.kind === 'worker') {
        return { backendStack: component.stack };
    }
    if (component.kind === 'frontend') {
        return { frontendStack: component.stack };
    }
    if (component.kind === 'library') {
        return { libraryStack: component.stack };
    }
    return undefined;
}
function resolveComponentModulesRoot(component, moduleRoots) {
    if (component.path === '.') {
        return moduleRoots.find((root) => root !== '.' && !root.includes('/')) ?? moduleRoots[0];
    }
    const componentPrefix = `${component.path}/`;
    return moduleRoots.find((root) => root === component.path || root.startsWith(componentPrefix));
}
function resolveProposalComponents(detection) {
    if (detection.topology.topology !== 'monorepo' &&
        (detection.detectedComponents?.length ?? 0) <= 1) {
        return undefined;
    }
    const components = (detection.detectedComponents ?? [])
        .filter((component) => isArchitectureComponentKind(component.kind))
        .filter((component, _index, allComponents) => isDefaultGovernedComponent(component, allComponents))
        .map((component) => {
        const projectKind = toComponentProjectKind(component.kind);
        const stacks = toComponentStacks(component);
        const componentModulesRoot = resolveComponentModulesRoot(component, detection.modules?.moduleRoots ?? []);
        return {
            id: component.id,
            name: component.name,
            path: component.path,
            type: toComponentType(component.kind),
            kind: component.kind,
            ...(component.stack ? { stack: component.stack } : {}),
            ...(projectKind ? { projectKinds: [projectKind] } : {}),
            ...(stacks ? { stacks } : {}),
            ...(componentModulesRoot ? { structure: { modulesRoot: componentModulesRoot } } : {}),
            ...(component.apiStyle && component.apiStyle !== 'unknown'
                ? { apiStyle: component.apiStyle === 'none' ? 'none' : component.apiStyle }
                : {}),
            ...(component.database && component.database !== 'unknown'
                ? {
                    database: component.database === 'postgresql' || component.database === 'mysql'
                        ? component.database
                        : 'none',
                }
                : {}),
        };
    });
    return components.length > 0 ? components : undefined;
}
function resolveResourceOwnerComponent(detection) {
    const backendComponents = getDefaultGovernedBackendComponents(detection);
    return backendComponents.find((component) => component.kind === 'backend') ??
        backendComponents[0];
}
function resourceIdFor(ownerId, suffix) {
    if (suffix === 'api' && /(^|-)api$/u.test(ownerId)) {
        return ownerId;
    }
    if (suffix === 'database') {
        return `${ownerId}-db`
            .replace(/[^a-z0-9_-]+/giu, '-')
            .replace(/^-+|-+$/gu, '')
            .toLowerCase();
    }
    return `${ownerId}-${suffix}`
        .replace(/[^a-z0-9_-]+/giu, '-')
        .replace(/^-+|-+$/gu, '')
        .toLowerCase();
}
function readableResourceName(componentName, suffix, provider) {
    const unscopedName = componentName.includes('/')
        ? componentName.slice(componentName.lastIndexOf('/') + 1)
        : componentName;
    const cleanName = unscopedName
        .replace(/^@/u, '')
        .replace(/[-_]+/gu, ' ')
        .trim();
    if (suffix === 'api') {
        return /\bapi$/iu.test(cleanName) ? cleanName.toUpperCase() : `${cleanName} API`;
    }
    if (provider === 'postgresql') {
        return 'Postgres';
    }
    return /\b(db|database)$/iu.test(cleanName) ? cleanName : `${cleanName} Database`;
}
function resolveProposalResources(input) {
    if (input.detection.topology.topology !== 'monorepo' &&
        (input.detection.detectedComponents?.length ?? 0) <= 1) {
        return undefined;
    }
    const resources = [];
    const usedIds = new Set();
    const addResource = (resource) => {
        if (!resource.id || usedIds.has(resource.id)) {
            return;
        }
        usedIds.add(resource.id);
        resources.push(resource);
    };
    for (const component of getDefaultGovernedBackendComponents(input.detection)) {
        if (component.apiStyle && component.apiStyle !== 'unknown' && component.apiStyle !== 'none') {
            addResource({
                id: resourceIdFor(component.id, 'api'),
                name: readableResourceName(component.name, 'api', component.apiStyle),
                type: 'api',
                provider: component.apiStyle,
                ownerComponent: component.id,
                component: component.id,
                components: [component.id],
            });
        }
        if (component.database && component.database !== 'unknown' && component.database !== 'none') {
            addResource({
                id: component.database === 'postgresql' ? 'postgres' : resourceIdFor(component.id, 'database'),
                name: readableResourceName(component.name, 'database', component.database),
                type: 'database',
                provider: component.database,
                ownerComponent: component.id,
                component: component.id,
                components: [component.id],
            });
        }
    }
    for (const component of getDataComponents(input.detection)) {
        if (component.database && component.database !== 'unknown' && component.database !== 'none') {
            addResource({
                id: component.database === 'postgresql' ? 'postgres' : resourceIdFor(component.id, 'database'),
                name: readableResourceName(component.name, 'database', component.database),
                type: 'database',
                provider: component.database,
                ownerComponent: component.id,
                component: component.id,
                components: [component.id],
            });
        }
    }
    const owner = resolveResourceOwnerComponent(input.detection);
    const detectedDatabase = input.database;
    const hasDatabaseResource = resources.some((resource) => resource.type === 'database');
    if (owner &&
        !hasDatabaseResource &&
        detectedDatabase &&
        detectedDatabase !== 'unknown' &&
        detectedDatabase !== 'none') {
        addResource({
            id: detectedDatabase === 'postgresql' ? 'postgres' : resourceIdFor(owner.id, 'database'),
            name: readableResourceName(owner.name, 'database', detectedDatabase),
            type: 'database',
            provider: detectedDatabase,
            ownerComponent: owner.id,
            component: owner.id,
            components: [owner.id],
        });
    }
    const hasApiResource = resources.some((resource) => resource.type === 'api');
    if (owner &&
        !hasApiResource &&
        input.apiStyle &&
        input.apiStyle !== 'unknown' &&
        input.apiStyle !== 'none') {
        addResource({
            id: resourceIdFor(owner.id, 'api'),
            name: readableResourceName(owner.name, 'api', input.apiStyle),
            type: 'api',
            provider: input.apiStyle,
            ownerComponent: owner.id,
            component: owner.id,
            components: [owner.id],
        });
    }
    return resources.length > 0
        ? resources.sort((left, right) => (left.id ?? '').localeCompare(right.id ?? ''))
        : undefined;
}
function hasAttributableBackendRoot(detection) {
    return getBackendComponents(detection).length > 0;
}
function isGenericLibraryStack(stack) {
    return stack === 'node_typescript' ||
        stack === 'node_javascript' ||
        stack === 'python' ||
        stack === 'go' ||
        stack === 'kotlin' ||
        stack === 'terraform' ||
        stack === 'ansible';
}
function hasProjectKindEvidence(detection, patterns) {
    const evidence = detection.projectKinds?.evidence ?? [];
    return evidence.some((entry) => patterns.some((pattern) => pattern.test(entry)));
}
function resolveSingleProjectGenericKinds(detection, selectedAdapterId, selectedHints, evidence) {
    if (detection.topology.topology !== 'single_project' ||
        !selectedAdapterId ||
        (0, stackAdapters_1.getStackAdapterById)(selectedAdapterId).category !== 'generic-language' ||
        !(selectedHints.includes('backend') && selectedHints.includes('library'))) {
        return undefined;
    }
    const hasFrameworkBackendCandidate = (detection.stacks.candidates ?? []).some((candidate) => {
        const adapter = (0, stackAdapters_1.getStackAdapterById)(candidate.adapterId);
        return adapter.category === 'framework' && adapter.id !== selectedAdapterId;
    });
    if (hasFrameworkBackendCandidate) {
        return undefined;
    }
    const hasServiceBackendEvidence = hasProjectKindEvidence(detection, [
        /requirements\.txt/u,
        /composer\.json/u,
        /pom\.xml/u,
        /build\.gradle/u,
        /openapi/u,
        /db\/ or migrations/u,
        /repository-layer/u,
    ]);
    const hasCliEntrypointEvidence = hasProjectKindEvidence(detection, [
        /cmd\/ entrypoint/u,
        /CLI-style entrypoint/u,
    ]);
    const hasLibraryEvidence = hasProjectKindEvidence(detection, [
        /exports field/u,
        /main\/module\/types fields/u,
        /src\/index/u,
        /pyproject\.toml/u,
        /setup\.py/u,
        /go\.mod/u,
        /Python package __init__\.py/u,
        /reusable module folders/u,
    ]);
    const selected = hasLibraryEvidence && !hasServiceBackendEvidence ? 'library' : 'backend';
    addEvidence(evidence, `Reduced single-project generic ${selectedAdapterId} project kind to ${selected}`);
    if (selected === 'library' && hasCliEntrypointEvidence) {
        addEvidence(evidence, 'Treated CLI entrypoint as package tooling rather than backend service evidence');
    }
    return [selected];
}
function normalizeDetectedBackendStack(value) {
    if (value === 'springboot') {
        return 'spring';
    }
    if (typeof value !== 'string') {
        return undefined;
    }
    const adapter = (0, stackAdapters_1.getStackAdapterById)(value);
    const backendStacks = new Set([
        'node_typescript',
        'express',
        'nestjs',
        'java',
        'spring',
        'fastapi',
        'django',
        'flask',
        'python',
        'php',
        'laravel',
        'go',
        'dotnet',
        'ruby_rails',
        'kotlin',
        'kotlin_spring',
        'rust',
        'other',
    ]);
    return backendStacks.has(adapter.id) && adapter.id !== 'other'
        ? adapter.id
        : undefined;
}
function resolveConcreteBackendStackSelection(stacks) {
    const candidates = uniqueInOrder(stacks
        .map((stack) => normalizeDetectedBackendStack(stack))
        .filter((stack) => Boolean(stack)));
    if (candidates.length === 0) {
        return { candidates, ambiguous: false, reason: 'none' };
    }
    if (candidates.length === 1) {
        return { selected: candidates[0], candidates, ambiguous: false, reason: 'single' };
    }
    const frameworkCandidates = candidates.filter((stack) => (0, stackAdapters_1.getStackAdapterById)(stack).category === 'framework');
    if (frameworkCandidates.length === 1) {
        return {
            selected: frameworkCandidates[0],
            candidates,
            ambiguous: false,
            reason: 'framework-preferred',
        };
    }
    return { candidates, ambiguous: true, reason: 'ambiguous' };
}
function compatibleGenericBackendStacks(stack) {
    switch (stack) {
        case 'express':
        case 'nestjs':
            return ['node_typescript', 'node_javascript'];
        case 'spring':
            return ['java'];
        case 'fastapi':
        case 'django':
        case 'flask':
            return ['python'];
        case 'laravel':
            return ['php'];
        case 'kotlin_spring':
            return ['kotlin'];
        default:
            return [];
    }
}
function isFrameworkBackendStack(stack) {
    return (0, stackAdapters_1.getStackAdapterById)(stack).category === 'framework';
}
function getBackendCandidateByStack(detection, stack) {
    return detection.stacks.candidates?.find((candidate) => normalizeDetectedBackendStack(candidate.adapterId) === stack);
}
function isLikelyFrontendNodeToolingStack(detection, stack, selectedStack) {
    return (stack === 'node_typescript' || stack === 'node_javascript') &&
        selectedStack !== 'node_typescript' &&
        selectedStack !== 'node_javascript' &&
        !getBackendComponents(detection).some((component) => component.stack === stack &&
            component.confidence === 'high' &&
            component.governanceRole === 'runtime' &&
            isDefaultGovernedComponent(component, detection.detectedComponents ?? []));
}
function isCredibleCompetingSingleProjectBackendCandidate(detection, stack, selectedStack) {
    if (compatibleGenericBackendStacks(selectedStack).includes(stack)) {
        return false;
    }
    if (isLikelyFrontendNodeToolingStack(detection, stack, selectedStack)) {
        return false;
    }
    const candidate = getBackendCandidateByStack(detection, stack);
    if (!candidate || candidate.confidence !== 'high') {
        return false;
    }
    return true;
}
function resolveSingleProjectBackendStackFromRuntimeComponent(detection, backendComponents, detectedBackendStacks) {
    if (detection.topology.topology !== 'single_project') {
        return undefined;
    }
    const allComponents = detection.detectedComponents ?? [];
    const runtimeBackendComponents = backendComponents
        .filter((component) => component.confidence === 'high' &&
        component.governanceRole === 'runtime' &&
        isDefaultGovernedComponent(component, allComponents));
    const runtimeBackendStacks = uniqueInOrder(runtimeBackendComponents
        .map((component) => normalizeDetectedBackendStack(component.stack))
        .filter((stack) => Boolean(stack)));
    if (runtimeBackendStacks.length !== 1) {
        return undefined;
    }
    const selectedStack = normalizeDetectedBackendStack(detection.stacks.selectedAdapterId);
    const componentStack = runtimeBackendStacks[0];
    if (selectedStack !== componentStack) {
        return undefined;
    }
    const competingCandidates = uniqueInOrder(detectedBackendStacks)
        .filter((stack) => stack !== componentStack)
        .filter((stack) => isCredibleCompetingSingleProjectBackendCandidate(detection, stack, componentStack));
    return competingCandidates.length === 0 ? componentStack : undefined;
}
function backendComponentSignificance(component) {
    let score = 1;
    if (component.governanceRole === 'runtime') {
        score += 1;
    }
    if (component.confidence === 'high') {
        score += 1;
    }
    else if (component.confidence === 'medium') {
        score += 0.5;
    }
    if (component.apiStyle && component.apiStyle !== 'none' && component.apiStyle !== 'unknown') {
        score += 2;
    }
    if ((component.evidence ?? []).some((entry) => /architecture root signal:\s*backend_app/iu.test(entry))) {
        score += 1;
    }
    return score;
}
function resolveDominantBackendFrameworkFromComponents(components) {
    const relevantBackendComponents = components
        .filter((component) => component.kind === 'backend' || component.kind === 'worker')
        .filter((component, _index, allComponents) => isDefaultGovernedComponent(component, allComponents))
        .filter((component) => !hasSupportRoleEvidence(component) || hasIndependentRuntimeEvidence(component))
        .filter((component) => component.governanceRole !== 'support' && Boolean(component.stack));
    const candidates = uniqueInOrder(relevantBackendComponents
        .map((component) => normalizeDetectedBackendStack(component.stack))
        .filter((stack) => Boolean(stack)));
    if (candidates.length === 0) {
        return undefined;
    }
    const frameworkScores = new Map();
    const genericStacks = new Set();
    for (const component of relevantBackendComponents) {
        const stack = normalizeDetectedBackendStack(component.stack);
        if (!stack) {
            continue;
        }
        if (isFrameworkBackendStack(stack)) {
            frameworkScores.set(stack, (frameworkScores.get(stack) ?? 0) + backendComponentSignificance(component));
        }
        else {
            genericStacks.add(stack);
        }
    }
    const frameworkEntries = [...frameworkScores.entries()]
        .sort((left, right) => {
        const scoreDiff = right[1] - left[1];
        return scoreDiff !== 0 ? scoreDiff : left[0].localeCompare(right[0]);
    });
    if (frameworkEntries.length === 0) {
        return resolveConcreteBackendStackSelection(candidates);
    }
    if (frameworkEntries.length === 1) {
        const selected = frameworkEntries[0][0];
        return {
            selected,
            candidates,
            ambiguous: false,
            reason: 'framework-preferred',
        };
    }
    const [topStack, topScore] = frameworkEntries[0];
    const [, nextScore] = frameworkEntries[1];
    const compatibleGenericStacks = new Set(compatibleGenericBackendStacks(topStack));
    const incompatibleGenericStacks = [...genericStacks].filter((stack) => !compatibleGenericStacks.has(stack));
    if (topScore >= nextScore * 2 && incompatibleGenericStacks.length === 0) {
        return {
            selected: topStack,
            candidates,
            ambiguous: false,
            reason: 'dominant-framework',
        };
    }
    return {
        candidates,
        ambiguous: true,
        reason: 'ambiguous',
    };
}
function resolveNormalizedProjectKinds(detection, evidence) {
    const heuristicKinds = (detection.projectKinds?.kinds ?? []).filter(isProposalProjectKind);
    if (detection.topology.topology === 'monorepo') {
        const componentKinds = [
            ...(getBackendComponents(detection).length > 0 ? ['backend'] : []),
            ...(getFrontendComponents(detection).length > 0 ? ['frontend'] : []),
            ...(getLibraryComponents(detection).length > 0 || getDataComponents(detection).length > 0 ? ['library'] : []),
        ];
        if (componentKinds.length > 0) {
            addEvidence(evidence, 'Normalized monorepo project kinds from detected component roots');
            return uniqueSortedKinds(componentKinds);
        }
    }
    const selectedAdapterId = detection.stacks.selectedAdapterId;
    const selectedCandidate = getSelectedCandidate(detection);
    const selectedAdapter = (0, stackAdapters_1.getStackAdapterById)(selectedAdapterId);
    const selectedHints = selectedCandidate?.projectKindHints ??
        (selectedAdapterId
            ? (0, stackAdapters_1.getStackAdapterById)(selectedAdapterId).resolveProjectKinds?.(selectedCandidate ?? {
                adapterId: selectedAdapterId,
                confidence: 'low',
                score: 0,
                evidence: [],
            }) ?? []
            : []);
    let normalizedKinds = [];
    const genericSingleProjectKinds = resolveSingleProjectGenericKinds(detection, selectedAdapterId, selectedHints, evidence);
    if (genericSingleProjectKinds) {
        normalizedKinds = genericSingleProjectKinds;
    }
    else if (detection.topology.topology === 'single_project' && selectedHints.length > 0 && selectedAdapter.category === 'framework') {
        normalizedKinds = uniqueSortedKinds(selectedHints);
        addEvidence(evidence, `Normalized project kinds from selected adapter '${selectedAdapter.id}' hints`);
    }
    else if (detection.topology.topology === 'monorepo' && selectedHints.length > 0) {
        normalizedKinds = uniqueSortedKinds([...heuristicKinds, ...selectedHints]);
        if (normalizedKinds.includes('library') &&
            !selectedHints.includes('library') &&
            (detection.architectureStyleSignals?.sharedPackageCount ?? 0) === 0) {
            normalizedKinds = normalizedKinds.filter((kind) => kind !== 'library');
        }
        addEvidence(evidence, 'Normalized monorepo project kinds from adapter hints plus heuristic evidence');
    }
    else if (heuristicKinds.length > 0) {
        normalizedKinds = uniqueSortedKinds(heuristicKinds);
    }
    else if (selectedHints.length > 0) {
        normalizedKinds = uniqueSortedKinds(selectedHints);
        addEvidence(evidence, `Used selected adapter '${selectedAdapter.id}' hints as proposal project kinds fallback`);
    }
    if (normalizedKinds.length === 0 && detection.stacks.frontendStacks.length > 0) {
        normalizedKinds = ['frontend'];
        addEvidence(evidence, 'Normalized project kinds from detected frontend stack evidence');
    }
    else if (normalizedKinds.length === 0 && detection.stacks.backendStacks.length > 0) {
        normalizedKinds = ['backend'];
        addEvidence(evidence, 'Normalized project kinds from detected backend stack evidence');
    }
    return normalizedKinds;
}
function resolveArchitectureStyle(detection, projectKinds, evidence) {
    const architectureStyleEvidence = [];
    const topology = detection.topology.topology;
    const modulesRoot = detection.modules?.modulesRoot;
    const moduleCount = detection.modules?.modules.length ?? 0;
    const architectureSignals = detection.architectureStyleSignals;
    const backendAppCount = architectureSignals?.backendAppCount ?? (projectKinds.includes('backend') ? 1 : 0);
    const frontendAppCount = architectureSignals?.frontendAppCount ?? (projectKinds.includes('frontend') ? 1 : 0);
    const sharedPackageCount = architectureSignals?.sharedPackageCount ?? 0;
    const strongMicroserviceCount = architectureSignals?.strongMicroserviceCount ?? 0;
    const serviceCommunicationCount = architectureSignals?.serviceCommunicationCount ?? 0;
    const deploymentConfiguredServiceCount = architectureSignals?.deploymentConfiguredServiceCount ?? 0;
    const envConfiguredServiceCount = architectureSignals?.envConfiguredServiceCount ?? 0;
    const openApiServiceCount = architectureSignals?.openApiServiceCount ?? 0;
    if (topology === 'monorepo') {
        addEvidence(architectureStyleEvidence, 'Detected monorepo topology');
    }
    if (backendAppCount === 1) {
        addEvidence(architectureStyleEvidence, 'Detected single backend app');
    }
    else if (backendAppCount > 1) {
        addEvidence(architectureStyleEvidence, `Detected ${backendAppCount} backend app roots`);
    }
    if (frontendAppCount > 0) {
        addEvidence(architectureStyleEvidence, `Detected ${frontendAppCount} frontend app root${frontendAppCount === 1 ? '' : 's'}`);
    }
    if (sharedPackageCount > 0) {
        addEvidence(architectureStyleEvidence, `Detected shared packages (${sharedPackageCount})`);
    }
    if (modulesRoot) {
        addEvidence(architectureStyleEvidence, `Detected modules root at ${modulesRoot}`);
    }
    else if (moduleCount > 0) {
        addEvidence(architectureStyleEvidence, `Detected ${moduleCount} module candidates`);
    }
    const hasStrongMicroserviceSignals = strongMicroserviceCount >= 2 &&
        (serviceCommunicationCount >= 1 || deploymentConfiguredServiceCount >= 2 || envConfiguredServiceCount >= 2 || openApiServiceCount >= 2);
    const hasMultipleComponentWorkspace = topology === 'monorepo' &&
        (backendAppCount + frontendAppCount + sharedPackageCount >= 2 ||
            (detection.detectedComponents ?? []).filter((component) => component.path !== '.').length >= 2);
    if (hasStrongMicroserviceSignals) {
        addEvidence(architectureStyleEvidence, `Detected ${strongMicroserviceCount} independent backend services with API, DB, and service-level operational config`);
        if (serviceCommunicationCount > 0) {
            addEvidence(architectureStyleEvidence, 'Detected service-to-service communication');
        }
        addEvidence(architectureStyleEvidence, 'Proposed Style: microservices');
        for (const item of architectureStyleEvidence) {
            addEvidence(evidence, item);
        }
        return {
            architectureStyle: 'microservices',
            architectureStyleEvidence,
        };
    }
    if (hasMultipleComponentWorkspace && !(backendAppCount === 1 && modulesRoot && frontendAppCount === 0 && sharedPackageCount === 0)) {
        addEvidence(architectureStyleEvidence, 'Detected multi-component monorepo workspace');
        addEvidence(architectureStyleEvidence, 'Proposed Style: multi_component_monorepo');
        for (const item of architectureStyleEvidence) {
            addEvidence(evidence, item);
        }
        return {
            architectureStyle: 'multi_component_monorepo',
            architectureStyleEvidence,
        };
    }
    if (backendAppCount === 1 && modulesRoot) {
        addEvidence(architectureStyleEvidence, 'Single backend app plus module boundaries favor a modular monolith');
    }
    else if (topology === 'monorepo' && backendAppCount === 1 && (frontendAppCount > 0 || sharedPackageCount > 0)) {
        addEvidence(architectureStyleEvidence, 'Monorepo contains one backend app plus frontend/shared packages');
    }
    else if (backendAppCount <= 1 && projectKinds.includes('backend')) {
        addEvidence(architectureStyleEvidence, 'No independent service boundaries detected');
    }
    else if (backendAppCount > 1) {
        addEvidence(architectureStyleEvidence, 'Multiple backend roots detected, but independent microservice boundaries were not strong enough');
    }
    else {
        return {
            architectureStyleEvidence,
        };
    }
    addEvidence(architectureStyleEvidence, 'Proposed Style: modular_monolith');
    for (const item of architectureStyleEvidence) {
        addEvidence(evidence, item);
    }
    return {
        architectureStyle: 'modular_monolith',
        architectureStyleEvidence,
    };
}
function resolveRoleApiStyleHint(detection, stackId, component) {
    if (component?.apiStyle) {
        return component.apiStyle;
    }
    if (!stackId) {
        return undefined;
    }
    const candidate = detection.stacks.candidates?.find((entry) => entry.adapterId === stackId);
    return candidate?.apiStyleHint ?? detection.apiDbHints?.api.apiStyle;
}
function resolveStackSelections(detection, projectKinds) {
    const selections = {};
    const backendComponents = getBackendComponents(detection);
    const frontendComponents = getFrontendComponents(detection);
    const libraryComponents = [...getLibraryComponents(detection), ...getDataComponents(detection)];
    if (projectKinds.includes('backend')) {
        const backendComponentStacks = uniqueInOrder(backendComponents
            .map((component) => component.stack)
            .filter((stack) => Boolean(stack)));
        const detectedBackendStacks = uniqueInOrder(detection.stacks.backendStacks);
        const preferredBackend = detection.topology.topology === 'monorepo'
            ? (resolveDominantBackendFrameworkFromComponents(detection.detectedComponents ?? []) ??
                resolveConcreteBackendStackSelection(backendComponentStacks.length > 0 ? backendComponentStacks : detectedBackendStacks)).selected
            : (resolveConcreteBackendStackSelection(detectedBackendStacks).selected ??
                resolveSingleProjectBackendStackFromRuntimeComponent(detection, backendComponents, detectedBackendStacks));
        if (preferredBackend) {
            selections.backend = preferredBackend;
        }
    }
    if (projectKinds.includes('frontend')) {
        const frontendComponentStack = frontendComponents
            .map((component) => component.stack)
            .find((stack) => Boolean(stack));
        const preferredFrontend = detection.topology.topology === 'monorepo'
            ? frontendComponentStack
            : detection.stacks.frontendStacks[0];
        if (preferredFrontend) {
            selections.frontend = preferredFrontend;
        }
    }
    if (projectKinds.includes('library')) {
        const libraryComponentStacks = uniqueInOrder(libraryComponents
            .map((component) => component.stack)
            .filter((stack) => isGenericLibraryStack(stack)));
        const selectedLibrary = detection.topology.topology === 'monorepo'
            ? libraryComponentStacks.length === 1
                ? libraryComponentStacks[0]
                : undefined
            : detection.stacks.selectedAdapterId;
        if (isGenericLibraryStack(selectedLibrary)) {
            selections.library = selectedLibrary;
        }
    }
    return selections;
}
function resolveProjectProfiles(detection, projectKinds, stackSelections, apiStyle) {
    const profiles = {};
    for (const kind of projectKinds) {
        if (kind === 'library') {
            continue;
        }
        const stackId = stackSelections[kind];
        if (!stackId) {
            continue;
        }
        const component = detection.detectedComponents.find((entry) => entry.stack === stackId && entry.kind === kind);
        profiles[kind] = (0, implementationProfileResolution_1.resolveImplementationProfile)({
            selectedAdapterId: stackId,
            selectedAdapterCategory: (0, stackAdapters_1.getStackAdapterById)(stackId).category,
            projectKinds: [kind],
            apiStyleHint: kind === 'backend' && apiStyle
                ? apiStyle
                : resolveRoleApiStyleHint(detection, stackId, component),
            databaseHints: detection.toolingHints?.databaseHints,
            toolingHints: detection.toolingHints?.toolingHints,
            repoTopology: detection.topology.topology === 'unknown' ? 'single_project' : detection.topology.topology,
        });
    }
    return profiles;
}
function resolveProposalImplementationProfile(detection, projectKinds, stackSelections, evidence, apiStyle) {
    if (projectKinds.includes('backend') && !stackSelections.backend) {
        return undefined;
    }
    const selectedAdapterId = detection.topology.topology === 'monorepo' && stackSelections.backend
        ? stackSelections.backend
        : detection.stacks.selectedAdapterId;
    const backendComponent = stackSelections.backend
        ? getBackendComponents(detection).find((component) => component.stack === stackSelections.backend)
        : undefined;
    const selectedAdapter = (0, stackAdapters_1.getStackAdapterById)(selectedAdapterId);
    const selectedCandidate = getSelectedCandidate(detection);
    const profile = (0, implementationProfileResolution_1.resolveImplementationProfile)({
        selectedAdapterId,
        selectedAdapterCategory: detection.stacks.selectedAdapterCategory ?? selectedAdapter.category,
        projectKinds: [...projectKinds],
        apiStyleHint: apiStyle ?? backendComponent?.apiStyle ?? selectedCandidate?.apiStyleHint ?? detection.apiDbHints?.api.apiStyle,
        databaseHints: detection.toolingHints?.databaseHints,
        toolingHints: detection.toolingHints?.toolingHints,
        repoTopology: detection.topology.topology === 'unknown' ? 'single_project' : detection.topology.topology,
    });
    if (selectedAdapterId) {
        addEvidence(evidence, `Resolved implementation profile from selected adapter '${selectedAdapterId}'`);
    }
    return profile === 'other' ? undefined : profile;
}
function resolveProposalModulesRoot(detection) {
    const modulesRoot = detection.modules?.modulesRoot;
    if (!modulesRoot || detection.topology.topology !== 'monorepo') {
        return modulesRoot;
    }
    if (['apps', 'packages', 'services', 'libs'].includes(modulesRoot)) {
        const componentContainers = new Set((detection.detectedComponents ?? [])
            .map((component) => component.path.split('/')[0])
            .filter((segment) => ['apps', 'packages', 'services', 'libs'].includes(segment ?? '')));
        return componentContainers.size <= 1 ? modulesRoot : undefined;
    }
    const componentPaths = (detection.detectedComponents ?? [])
        .map((component) => component.path)
        .filter((componentPath) => componentPath !== '.' && componentPath.length > 0);
    if (componentPaths.some((componentPath) => modulesRoot.startsWith(`${componentPath}/`))) {
        return undefined;
    }
    return modulesRoot;
}
function resolveProposalApiStyle(detection) {
    if (detection.topology.topology === 'monorepo') {
        const apiStyle = getBackendComponents(detection)
            .map((component) => component.apiStyle)
            .find((value) => value === 'rest' || value === 'graphql');
        return apiStyle ?? 'none';
    }
    const detectedApiStyle = detection.apiDbHints?.api.apiStyle;
    return detectedApiStyle && detectedApiStyle !== 'unknown' ? detectedApiStyle : undefined;
}
function resolveProposalDatabase(input) {
    const toSupportedProposalDatabase = (value) => {
        if (value === 'postgresql' || value === 'mysql' || value === 'none') {
            return value;
        }
        return undefined;
    };
    const supportedDatabaseHints = uniqueSorted(input.databaseHints
        .map((value) => toSupportedProposalDatabase(value))
        .filter((value) => Boolean(value)));
    const singleSupportedHint = supportedDatabaseHints.length === 1 ? supportedDatabaseHints[0] : undefined;
    const detectedDatabase = input.detection.apiDbHints?.database.database;
    if (input.detection.topology.topology === 'monorepo') {
        const componentDatabase = getBackendComponents(input.detection)
            .map((component) => component.database)
            .find((value) => Boolean(value) && value !== 'unknown' && value !== 'none');
        const supportedComponentDatabase = toSupportedProposalDatabase(componentDatabase);
        if (supportedComponentDatabase) {
            return supportedComponentDatabase;
        }
        if (hasAttributableBackendRoot(input.detection)) {
            return toSupportedProposalDatabase(detectedDatabase) ??
                singleSupportedHint ??
                'none';
        }
        return 'none';
    }
    return toSupportedProposalDatabase(detectedDatabase) ??
        singleSupportedHint ??
        'none';
}
function resolveConfidence(proposal, detection) {
    let score = 0;
    if (proposal.projectKinds && proposal.projectKinds.length > 0) {
        score += 1;
    }
    if (proposal.architectureStyle) {
        score += 2;
    }
    if (proposal.modulesRoot) {
        score += 1;
    }
    if (proposal.apiStyle) {
        score += 1;
    }
    if (proposal.database) {
        score += 1;
    }
    if (proposal.implementationProfile) {
        score += 1;
    }
    if ((proposal.modules?.length ?? 0) > 0) {
        score += 1;
    }
    if ((proposal.toolingHints?.length ?? 0) > 0) {
        score += 1;
    }
    if (detection.topology.confidence === 'high') {
        score += 1;
    }
    if (detection.stacks.confidence === 'high') {
        score += 1;
    }
    if (detection.modules?.confidence === 'high') {
        score += 1;
    }
    if (detection.apiDbHints?.confidence === 'high') {
        score += 1;
    }
    if (detection.toolingHints?.confidence === 'high') {
        score += 1;
    }
    if (score >= 9) {
        return 'high';
    }
    if (score >= 5) {
        return 'medium';
    }
    return 'low';
}
function resolveProposalReasons(input) {
    const reasons = {};
    const selectedStackIds = uniqueSorted(Object.values(input.stackSelections)
        .filter((stack) => Boolean(stack)));
    const selectedStackReasons = selectedStackIds
        .flatMap((stackId) => input.detection.stacks.candidates?.find((candidate) => candidate.adapterId === stackId)?.evidence ?? []);
    if (selectedStackReasons.length > 0) {
        reasons.framework = uniqueLimited(selectedStackReasons);
    }
    if (input.apiStyle && input.apiStyle !== 'unknown') {
        reasons.api = input.apiStyle === 'none'
            ? uniqueLimited(input.detection.apiDbHints?.api.evidence ?? ['No API artifacts detected for current project profile'], 4)
            : uniqueLimited(input.detection.apiDbHints?.api.evidence ?? [], 4);
    }
    if (input.database && input.database !== 'unknown') {
        const databaseEvidence = [
            ...(input.detection.apiDbHints?.database.evidence ?? []),
            ...(input.detection.toolingHints?.evidence ?? []).filter((entry) => /prisma|datasource|database|orm|jpa|entity framework|sqlalchemy|alembic/iu.test(entry)),
        ];
        reasons.database = input.database === 'none'
            ? uniqueLimited(databaseEvidence.length > 0 ? databaseEvidence : ['No database artifacts detected for current project profile'], 4)
            : uniqueLimited(databaseEvidence, 4);
    }
    if ((input.detection.toolingHints?.toolingHints.length ?? 0) > 0) {
        reasons.tooling = uniqueLimited(input.detection.toolingHints?.evidence ?? [], 5);
    }
    if (input.architectureStyleEvidence.length > 0) {
        reasons.architectureStyle = uniqueLimited(input.architectureStyleEvidence, 5);
    }
    if (input.modulesRoot || (input.moduleRoots?.length ?? 0) > 0) {
        reasons.modulesRoot = uniqueLimited([
            ...(input.modulesRoot ? [`Detected modules root at ${input.modulesRoot}`] : []),
            ...((input.moduleRoots ?? []).length > 0 ? [`Detected module roots: ${(input.moduleRoots ?? []).join(', ')}`] : []),
            ...(input.detection.modules?.evidence ?? []),
        ], 4);
    }
    return Object.keys(reasons).length > 0 ? reasons : undefined;
}
function buildArchitectureProposal(detection) {
    const evidence = [];
    addEvidence(evidence, `Detected ${detection.topology.topology} topology`);
    const projectKinds = resolveNormalizedProjectKinds(detection, evidence);
    const architectureStyleDecision = resolveArchitectureStyle(detection, projectKinds, evidence);
    const architectureStyle = architectureStyleDecision.architectureStyle;
    const stackSelections = resolveStackSelections(detection, projectKinds);
    const apiStyle = resolveProposalApiStyle(detection);
    const projectProfiles = resolveProjectProfiles(detection, projectKinds, stackSelections, apiStyle);
    const implementationProfile = resolveProposalImplementationProfile(detection, projectKinds, stackSelections, evidence, apiStyle);
    const modulesRoot = resolveProposalModulesRoot(detection);
    const moduleRoots = detection.modules?.moduleRoots;
    if (modulesRoot) {
        addEvidence(evidence, `Detected modules root at ${modulesRoot}`);
    }
    else if ((moduleRoots?.length ?? 0) > 0) {
        addEvidence(evidence, `Detected module roots: ${moduleRoots.join(', ')}`);
    }
    if (apiStyle) {
        addEvidence(evidence, apiStyle === 'none' ? 'Detected no public API signals' : `Detected ${apiStyle.toUpperCase()} API`);
    }
    const detectedDatabase = detection.apiDbHints?.database.database;
    const databaseHints = uniqueSorted([
        ...(detection.toolingHints?.databaseHints ?? []),
        ...(detection.apiDbHints?.database.databaseHints ?? []),
        ...(detectedDatabase && detectedDatabase !== 'unknown' && detectedDatabase !== 'none'
            ? [detectedDatabase]
            : []),
    ]);
    const database = resolveProposalDatabase({ detection, databaseHints });
    const authStyle = apiStyle && apiStyle !== 'none' ? 'jwt' : 'none';
    const components = resolveProposalComponents(detection);
    const resources = resolveProposalResources({ detection, database, apiStyle });
    const moduleCandidates = resolveModuleCandidates(detection, resources ?? []);
    const moduleCandidateGroups = groupModuleCandidates(moduleCandidates);
    const modules = moduleCandidates
        .filter((module) => module.selectedByDefault)
        .map((module) => module.name)
        .filter((name) => name.length > 0);
    if (moduleCandidates.length > 0) {
        addEvidence(evidence, `Detected ${moduleCandidates.length} module candidates`);
    }
    if (modules.length > 0) {
        addEvidence(evidence, `Preselected ${modules.length} architecture module candidates`);
    }
    if (database && database !== 'none') {
        addEvidence(evidence, `Detected ${database} database`);
    }
    else if (database === 'none') {
        addEvidence(evidence, 'Detected no database signals');
    }
    if (authStyle === 'none') {
        addEvidence(evidence, 'Detected no authentication boundary signals');
    }
    if ((detection.toolingHints?.toolingHints.length ?? 0) > 0) {
        addEvidence(evidence, `Detected tooling hints: ${(detection.toolingHints?.toolingHints ?? []).join(', ')}`);
    }
    const proposalReasons = resolveProposalReasons({
        detection,
        stackSelections,
        architectureStyleEvidence: architectureStyleDecision.architectureStyleEvidence,
        modulesRoot,
        moduleRoots,
        apiStyle,
        database,
    });
    const proposalCore = {
        ...(projectKinds.length > 0 ? { projectKinds } : {}),
        ...(architectureStyle ? { architectureStyle } : {}),
        ...((architectureStyleDecision.architectureStyleEvidence.length ?? 0) > 0
            ? { architectureStyleEvidence: uniqueSorted(architectureStyleDecision.architectureStyleEvidence) }
            : {}),
        ...(modulesRoot ? { modulesRoot } : {}),
        ...((moduleRoots?.length ?? 0) > 0 ? { moduleRoots: uniqueSorted(moduleRoots ?? []) } : {}),
        ...(apiStyle ? { apiStyle } : {}),
        ...(database ? { database } : {}),
        ...(authStyle ? { authStyle } : {}),
        ...(databaseHints.length > 0 ? { databaseHints } : {}),
        ...(implementationProfile ? { implementationProfile } : {}),
        ...(Object.keys(stackSelections).length > 0 ? { stackSelections } : {}),
        ...(Object.keys(projectProfiles).length > 0 ? { projectProfiles } : {}),
        ...(components ? { components } : {}),
        ...(resources ? { resources } : {}),
        ...((detection.toolingHints?.toolingHints.length ?? 0) > 0
            ? { toolingHints: uniqueSorted(detection.toolingHints?.toolingHints ?? []) }
            : {}),
        ...(modules.length > 0 ? { modules: uniqueSorted(modules) } : {}),
        ...(moduleCandidates.length > 0 ? { moduleCandidates } : {}),
        ...(moduleCandidateGroups ? { moduleCandidateGroups } : {}),
        ...((detection.detectedComponents?.length ?? 0) > 0 ? { detectedComponents: detection.detectedComponents } : {}),
        ...(proposalReasons ? { proposalReasons } : {}),
    };
    const confidence = resolveConfidence(proposalCore, detection);
    if (architectureStyle) {
        addEvidence(evidence, `Proposed ${architectureStyle} architecture`);
    }
    return {
        ...proposalCore,
        confidence,
        evidence: uniqueSorted(evidence),
    };
}
//# sourceMappingURL=architectureProposalBuilder.js.map