"use strict";
// team-supreme.ts — Supreme Team Intelligence Layer
// Vibe v3-level team profiling: DNA, knowledge map, health scoring, handoff quality.
// Additive layer — reads from existing team-collaboration DB, adds supreme insights.
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildTeamSupremeContext = buildTeamSupremeContext;
exports.formatTeamContext = formatTeamContext;
const database_1 = require("../../06-memory/database/database");
function getAllMembers() {
    const db = (0, database_1.getDb)();
    try {
        const members = db.prepare('SELECT name, email, commit_count, skills, project FROM collaborators ORDER BY commit_count DESC LIMIT 20').all();
        return members.map((m) => {
            // Get files from session_files for this member's sessions
            let files = [];
            try {
                files = db.prepare(`SELECT DISTINCT sf.file_path FROM session_files sf
           JOIN sessions s ON sf.session_id = s.id
           WHERE s.project = ? OR s.project = ?
           ORDER BY sf.last_touched DESC LIMIT 10`).all(m.project || m.name || 'fivo-cell', m.name || 'fivo-cell');
                files = files.map((f) => f.file_path);
            }
            catch { }
            const commitRhythm = detectCommitRhythm(m.name);
            const codeStyleTags = detectMemberCodeStyle(m.name, files);
            const collabScore = calculateCollaborationScore(m.name);
            const busFactor = calculateBusFactorImpact(m.name, files);
            return {
                name: m.name,
                email: m.email || '',
                primaryFiles: files.slice(0, 8),
                expertiseAreas: inferExpertise(files),
                commitRhythm,
                codeStyleTags,
                aiUsagePattern: detectAiUsage(m.name),
                sessionPattern: detectSessionPattern(m.name),
                collaborationScore: collabScore,
                busFactorImpact: busFactor,
            };
        });
    }
    catch {
        return [];
    }
}
function detectCommitRhythm(name) {
    try {
        const db = (0, database_1.getDb)();
        const sessions = db.prepare(`SELECT start_time FROM sessions 
       WHERE project = (SELECT project FROM collaborators WHERE name = ? LIMIT 1)
       ORDER BY id DESC LIMIT 20`).all(name);
        if (sessions.length < 3)
            return 'unknown';
        let morning = 0, afternoon = 0, evening = 0, night = 0;
        for (const s of sessions) {
            if (!s.start_time)
                continue;
            const h = new Date(s.start_time).getHours();
            if (h >= 5 && h < 12)
                morning++;
            else if (h >= 12 && h < 17)
                afternoon++;
            else if (h >= 17 && h < 21)
                evening++;
            else
                night++;
        }
        const max = Math.max(morning, afternoon, evening, night);
        if (max === night)
            return 'night_owl';
        if (max === morning)
            return 'morning_coder';
        if (max === evening)
            return 'evening_developer';
        if (max === afternoon)
            return 'afternoon_person';
        return 'irregular';
    }
    catch {
        return 'unknown';
    }
}
function detectMemberCodeStyle(name, files) {
    const tags = [];
    try {
        const db = (0, database_1.getDb)();
        const styles = db.prepare(`SELECT pattern_key, pattern_value FROM style_profiles WHERE member_name = ?`).all(name);
        for (const s of styles) {
            if (s.pattern_key === 'change_size' && s.pattern_value === 'minimal')
                tags.push('minimal_changes');
            if (s.pattern_key === 'change_size' && s.pattern_value === 'thorough')
                tags.push('refactor_heavy');
            if (s.pattern_key === 'type_strictness' && s.pattern_value === 'strict')
                tags.push('strict_type');
            if (s.pattern_key === 'abstraction' && s.pattern_value === 'low')
                tags.push('flat_structure');
        }
    }
    catch { }
    if (files.length > 10)
        tags.push('wide_toucher');
    if (files.length <= 3)
        tags.push('focused');
    return tags;
}
function detectAiUsage(name) {
    try {
        const db = (0, database_1.getDb)();
        const sessions = db.prepare(`SELECT tool_name FROM sessions WHERE key_decisions LIKE ? ORDER BY id DESC LIMIT 10`).all(`%${name}%`);
        const tools = sessions.map((s) => s.tool_name).filter(Boolean);
        if (tools.length === 0)
            return 'unknown';
        const unique = new Set(tools);
        if (unique.size >= 3)
            return 'multi_tool';
        if (tools.filter((t) => t.includes('cursor')).length >= 5)
            return 'cursor_main';
        return 'single_tool';
    }
    catch {
        return 'unknown';
    }
}
function detectSessionPattern(name) {
    try {
        const db = (0, database_1.getDb)();
        const sessions = db.prepare(`SELECT start_time, end_time FROM sessions ORDER BY id DESC LIMIT 10`).all();
        if (sessions.length < 3)
            return 'unknown';
        let totalMinutes = 0;
        let validSessions = 0;
        for (const s of sessions) {
            if (s.start_time && s.end_time) {
                const dur = (new Date(s.end_time).getTime() - new Date(s.start_time).getTime()) / 60000;
                if (dur > 0 && dur < 480) {
                    totalMinutes += dur;
                    validSessions++;
                }
            }
        }
        const avg = validSessions > 0 ? totalMinutes / validSessions : 0;
        if (avg > 120)
            return 'deep_work';
        if (avg < 20)
            return 'fragmented';
        return 'normal';
    }
    catch {
        return 'unknown';
    }
}
function calculateCollaborationScore(name) {
    try {
        const db = (0, database_1.getDb)();
        const sharedFiles = db.prepare(`SELECT COUNT(DISTINCT sf.file_path) as count FROM session_files sf
       JOIN sessions s ON sf.session_id = s.id
       WHERE sf.file_path IN (
         SELECT DISTINCT sf2.file_path FROM session_files sf2
         WHERE sf2.session_id != sf.session_id
       )
       AND s.id IN (SELECT id FROM sessions LIMIT 50)`).get();
        const totalFiles = db.prepare(`SELECT COUNT(DISTINCT file_path) as count FROM session_files`).get();
        if (!totalFiles?.count)
            return 50;
        const ratio = (sharedFiles?.count || 0) / totalFiles.count;
        return Math.min(100, Math.round(ratio * 100 + 30));
    }
    catch {
        return 50;
    }
}
function calculateBusFactorImpact(name, files) {
    if (files.length === 0)
        return 20;
    // Higher = more critical if this person leaves
    const uniqueFileScore = Math.min(80, files.length * 3);
    return Math.min(100, uniqueFileScore + 10);
}
function inferExpertise(files) {
    const areas = [];
    const mapping = {
        auth: 'Authentication', login: 'Authentication', jwt: 'Authentication', oauth: 'Authentication',
        middleware: 'API Middleware', route: 'API Routing', api: 'API Design', controller: 'API Design',
        test: 'Testing', spec: 'Testing', jest: 'Testing', vitest: 'Testing',
        database: 'Database', db: 'Database', sql: 'Database', migration: 'Database',
        component: 'Frontend', ui: 'Frontend', style: 'Frontend', css: 'Frontend', layout: 'Frontend',
        config: 'Infrastructure', deploy: 'Infrastructure', ci: 'Infrastructure', docker: 'Infrastructure',
        package: 'Dependencies', import: 'Dependencies',
    };
    for (const f of files) {
        const lower = f.toLowerCase();
        for (const [key, area] of Object.entries(mapping)) {
            if (lower.includes(key) && !areas.includes(area))
                areas.push(area);
        }
    }
    return areas.length > 0 ? areas : ['General Development'];
}
function detectCrossMemberPatterns() {
    const patterns = [];
    try {
        const db = (0, database_1.getDb)();
        const blindspots = db.prepare(`SELECT file_path, category, COUNT(*) as count FROM code_patterns
       WHERE category IN ('null_safety', 'error_handling', 'type_safety')
       GROUP BY file_path, category
       HAVING COUNT(*) >= 2
       LIMIT 10`).all();
        for (const b of blindspots) {
            patterns.push({
                pattern: `repeated_${b.category}`,
                description: `File ${b.file_path} has ${b.count} ${b.category} issues — may be a weak area`,
                affectedMembers: [],
                severity: b.count >= 5 ? 'critical' : 'warning',
                firstSeen: new Date().toISOString(),
                recurrenceCount: b.count,
            });
        }
    }
    catch { }
    return patterns;
}
function buildKnowledgeMap(members) {
    const areaMap = new Map();
    for (const m of members) {
        for (const area of m.expertiseAreas) {
            const existing = areaMap.get(area) || { files: [], experts: [] };
            existing.files = [...new Set([...existing.files, ...m.primaryFiles])];
            if (!existing.experts.includes(m.name))
                existing.experts.push(m.name);
            areaMap.set(area, existing);
        }
    }
    const map = [];
    for (const [area, data] of areaMap) {
        const confidence = Math.min(100, data.experts.length * 25 + data.files.length * 3);
        const busFactor = data.experts.length;
        map.push({
            area,
            files: data.files.slice(0, 5),
            experts: data.experts,
            confidence,
            riskLevel: busFactor <= 1 ? 'critical' : busFactor <= 2 ? 'at_risk' : 'safe',
            busFactor,
        });
    }
    return map.sort((a, b) => a.riskLevel === 'critical' ? -1 : 0);
}
function buildCollaborationHealth(members, knowledgeMap) {
    const avgCollab = members.length > 0 ? Math.round(members.reduce((a, m) => a + m.collaborationScore, 0) / members.length) : 50;
    const silos = knowledgeMap.filter(k => k.riskLevel === 'critical');
    const spofs = silos.map(s => ({ area: s.area, person: s.experts[0] || 'unknown' }));
    const strengths = [];
    if (avgCollab >= 65)
        strengths.push('Strong cross-team collaboration');
    if (silos.length <= 1)
        strengths.push('Good knowledge distribution');
    if (members.length >= 3)
        strengths.push('Healthy team size');
    const risks = [];
    if (silos.length >= 3)
        risks.push(`${silos.length} knowledge silos — bus factor critical`);
    for (const sp of spofs)
        risks.push(`${sp.person} is single point of failure for ${sp.area}`);
    if (avgCollab < 40)
        risks.push('Low collaboration — members working in isolation');
    return {
        overallScore: Math.round((avgCollab * 0.4 + (100 - silos.length * 15) * 0.4 + Math.min(100, members.length * 10) * 0.2)),
        pairFrequency: 0,
        reviewSpeed: 'medium',
        knowledgeSpread: Math.round(100 - silos.length * 20),
        siloCount: silos.length,
        singlePointsOfFailure: spofs,
        strengths: strengths.length > 0 ? strengths : ['Team health still being analyzed'],
        risks: risks.length > 0 ? risks : ['No critical risks detected'],
    };
}
function buildTeamVibe(members, collaborationHealth) {
    const allTags = members.flatMap(m => m.codeStyleTags);
    const tagCounts = new Map();
    for (const t of allTags)
        tagCounts.set(t, (tagCounts.get(t) || 0) + 1);
    const rhythms = members.map(m => m.commitRhythm).filter(r => r !== 'unknown');
    const nightCount = rhythms.filter(r => r === 'night_owl').length;
    const morningCount = rhythms.filter(r => r === 'morning_coder').length;
    const summaryParts = [];
    if (tagCounts.get('minimal_changes') && tagCounts.get('minimal_changes') > members.length * 0.5) {
        summaryParts.push('team prefers minimal, focused changes');
    }
    if (nightCount > members.length * 0.5) {
        summaryParts.push('mostly night owls');
    }
    if (collaborationHealth.overallScore >= 60) {
        summaryParts.push('collaborates well');
    }
    return {
        dominantWorkflow: tagCounts.get('minimal_changes') ? 'minimal_changes' : 'balanced',
        dominantCommunication: 'varies_per_member',
        collectiveRiskTolerance: collaborationHealth.siloCount <= 1 ? 'high' : 'low',
        decisionStyle: 'varies_by_member',
        strengths: collaborationHealth.strengths,
        watchOut: collaborationHealth.risks,
        summary: summaryParts.length > 0 ? summaryParts.join(', ') + '.' : 'Team style still emerging.',
    };
}
function buildTeamSupremeContext() {
    const members = getAllMembers();
    const crossMemberPatterns = detectCrossMemberPatterns();
    const knowledgeMap = buildKnowledgeMap(members);
    const collaborationHealth = buildCollaborationHealth(members, knowledgeMap);
    const handoffQuality = [];
    const teamVibe = buildTeamVibe(members, collaborationHealth);
    return {
        members,
        crossMemberPatterns,
        knowledgeMap,
        collaborationHealth,
        handoffQuality,
        teamVibe,
    };
}
function formatTeamContext(ctx) {
    const lines = [];
    if (ctx.members.length === 0) {
        lines.push('👥 TEAM');
        lines.push('   No team members detected.');
        return lines.join('\n');
    }
    lines.push('👥 TEAM');
    // Team Vibe summary
    if (ctx.teamVibe.summary && ctx.teamVibe.summary !== 'Team style still emerging.') {
        lines.push(`   Vibe: ${ctx.teamVibe.summary}`);
    }
    // Members
    lines.push(`   Members: ${ctx.members.map(m => m.name).join(', ')}`);
    // Bus factor & health
    if (ctx.collaborationHealth.singlePointsOfFailure.length > 0) {
        lines.push(`   ⚠️  Bus factor: ${ctx.collaborationHealth.singlePointsOfFailure.length} single points of failure`);
        for (const sp of ctx.collaborationHealth.singlePointsOfFailure.slice(0, 3)) {
            lines.push(`      → ${sp.person} is the only one who knows ${sp.area}`);
        }
    }
    // Knowledge map critical
    const critical = ctx.knowledgeMap.filter(k => k.riskLevel === 'critical');
    if (critical.length > 0) {
        lines.push(`   Knowledge gaps: ${critical.map(k => k.area).join(', ')}`);
    }
    // Cross-member patterns
    if (ctx.crossMemberPatterns.length > 0) {
        const crit = ctx.crossMemberPatterns.filter(p => p.severity === 'critical');
        if (crit.length > 0) {
            lines.push(`   Team patterns: ${crit[0].description.substring(0, 80)}`);
        }
    }
    lines.push(`   Health score: ${ctx.collaborationHealth.overallScore}/100`);
    return lines.join('\n');
}
//# sourceMappingURL=team-supreme.js.map