// engine/spec-generators/issue-extractor.ts — SPEC-472: Convert ExtractedIssue to spec draft
// Per-source extractors live in subdirectory but are loaded dynamically when needed.
const FRONTEND_LABELS = new Set(['ui', 'ux', 'frontend', 'design', 'css', 'component']);
const BACKEND_LABELS = new Set(['api', 'backend', 'database', 'sql', 'server', 'rpc']);
const INFRA_LABELS = new Set(['infra', 'ci', 'cd', 'deploy', 'docker', 'kubernetes']);
const BUGFIX_LABELS = new Set(['bug', 'bugfix', 'fix', 'defect', 'broken']);
const DOCS_LABELS = new Set(['docs', 'documentation', 'readme']);
const REFACTOR_LABELS = new Set(['refactor', 'cleanup', 'tech-debt', 'rewrite']);
const HIGH_RISK_LABELS = new Set(['security', 'data-loss', 'breaking', 'critical', 'p0']);
const MEDIUM_RISK_LABELS = new Set(['p1', 'high-priority', 'auth', 'payments']);
export function inferSpecFromIssue(issue) {
    const lowerLabels = issue.labels.map((l) => l.toLowerCase());
    const lowerBody = issue.body.toLowerCase();
    return {
        specDraft: {
            title: issue.title,
            description: buildDescription(issue),
            target: inferTarget(lowerLabels, lowerBody),
            type: inferType(lowerLabels),
            scope: inferScope(issue),
            risk: inferRisk(lowerLabels),
            tags: dedupeTags([...lowerLabels, issue.source]),
            sourceIssue: {
                source: issue.source,
                id: issue.externalId,
                url: issue.url,
            },
        },
        rawIssue: issue,
    };
}
function buildDescription(issue) {
    const parts = [issue.body.trim()];
    if (issue.comments && issue.comments.length > 0) {
        parts.push('\n\n## Discussion\n' + issue.comments.map((c) => `- ${c}`).join('\n'));
    }
    if (issue.mentions && issue.mentions.length > 0) {
        parts.push('\n\n## Related\n' + issue.mentions.map((m) => `- ${m}`).join('\n'));
    }
    parts.push(`\n\n## Source\n${issue.source} ${issue.externalId}${issue.url ? ` — ${issue.url}` : ''}`);
    return parts.join('');
}
function inferTarget(labels, body) {
    if (labels.some((l) => FRONTEND_LABELS.has(l))) {
        return 'frontend';
    }
    if (labels.some((l) => BACKEND_LABELS.has(l))) {
        return 'backend';
    }
    if (labels.some((l) => INFRA_LABELS.has(l))) {
        return 'infrastructure';
    }
    if (/\bui\b|component|css|button/.test(body)) {
        return 'frontend';
    }
    if (/\bapi\b|endpoint|database|migration/.test(body)) {
        return 'backend';
    }
    return 'fullstack';
}
function inferType(labels) {
    if (labels.some((l) => BUGFIX_LABELS.has(l))) {
        return 'bugfix';
    }
    if (labels.some((l) => REFACTOR_LABELS.has(l))) {
        return 'refactor';
    }
    if (labels.some((l) => DOCS_LABELS.has(l))) {
        return 'docs';
    }
    if (labels.some((l) => INFRA_LABELS.has(l))) {
        return 'infra';
    }
    return 'feature';
}
function inferScope(issue) {
    const wordCount = issue.body.trim().split(/\s+/).length;
    if (wordCount < 30) {
        return 'trivial';
    }
    if (wordCount < 200) {
        return 'feature';
    }
    if (wordCount < 600) {
        return 'cross-module';
    }
    return 'architectural';
}
function inferRisk(labels) {
    if (labels.some((l) => HIGH_RISK_LABELS.has(l))) {
        return 'high';
    }
    if (labels.some((l) => MEDIUM_RISK_LABELS.has(l))) {
        return 'medium';
    }
    return 'low';
}
function dedupeTags(tags) {
    return Array.from(new Set(tags.filter((t) => t.length > 0)));
}
//# sourceMappingURL=issue-extractor.js.map