"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ensureOrganization = ensureOrganization;
exports.registerTeam = registerTeam;
exports.ingestTeamOutcomes = ingestTeamOutcomes;
exports.getTeamRankings = getTeamRankings;
exports.computeTeamDNA = computeTeamDNA;
exports.getAllTeamDNA = getAllTeamDNA;
exports.computeBenchmarks = computeBenchmarks;
exports.detectWorkflows = detectWorkflows;
exports.detectKnowledgeSilos = detectKnowledgeSilos;
exports.computeBusFactor = computeBusFactor;
exports.computeTeamRisk = computeTeamRisk;
exports.generateOrgPlaybooks = generateOrgPlaybooks;
exports.generateExecutiveInsights = generateExecutiveInsights;
exports.takeSnapshot = takeSnapshot;
exports.resetOrg = resetOrg;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const os = __importStar(require("os"));
// ═══════════════════════════════════════════════════════════════
// STORAGE
// ═══════════════════════════════════════════════════════════════
const STORE_PATH = path.join(os.homedir(), '.fivo', 'cell', 'org-intelligence.json');
function ensureDir() {
    const dir = path.dirname(STORE_PATH);
    if (!fs.existsSync(dir))
        fs.mkdirSync(dir, { recursive: true });
}
function loadStore() {
    ensureDir();
    try {
        if (fs.existsSync(STORE_PATH))
            return JSON.parse(fs.readFileSync(STORE_PATH, 'utf-8'));
    }
    catch { }
    return { orgs: {}, version: 1 };
}
function saveStore(data) {
    ensureDir();
    fs.writeFileSync(STORE_PATH, JSON.stringify(data, null, 2), 'utf-8');
}
// ═══════════════════════════════════════════════════════════════
// HELPERS
// ═══════════════════════════════════════════════════════════════
function classifyRisk(score) {
    if (score <= 20)
        return { level: 'low', score };
    if (score <= 50)
        return { level: 'medium', score };
    if (score <= 75)
        return { level: 'high', score };
    return { level: 'critical', score };
}
function classifyTeamStyle(sr, testingAdoption) {
    if (sr >= 0.8 && testingAdoption >= 0.7)
        return 'quality-driven';
    if (sr < 0.5 || testingAdoption < 0.3)
        return 'experiment-driven';
    if (testingAdoption >= 0.5 && sr >= 0.6)
        return 'stability-driven';
    return 'speed-driven';
}
// ═══════════════════════════════════════════════════════════════
// SYSTEM 1: ORGANIZATION REGISTRY
// ═══════════════════════════════════════════════════════════════
function ensureOrganization(orgId) {
    const store = loadStore();
    if (!store.orgs[orgId]) {
        store.orgs[orgId] = { teams: {}, members: {}, history: [], lastUpdated: Date.now() };
        saveStore(store);
    }
}
function registerTeam(orgId, teamId, name) {
    ensureOrganization(orgId);
    const store = loadStore();
    if (!store.orgs[orgId].teams[teamId]) {
        store.orgs[orgId].teams[teamId] = {
            teamId, name, memberCount: 0, totalPatterns: 0, totalOutcomes: 0,
            successCount: 0, failureCount: 0, successRate: 0, avgConfidence: 0, avgHealth: 0,
            topLanguages: [], topCategories: [],
            teamDNA: { style: 'stability-driven', riskLevel: 'low', riskScore: 0, testingAdoption: 0, ciAdoption: 0, reviewAdoption: 0 },
            periodStart: Date.now(), periodEnd: Date.now(),
        };
        saveStore(store);
    }
}
function ingestTeamOutcomes(orgId, teamId, memberId, outcomes) {
    ensureOrganization(orgId);
    registerTeam(orgId, teamId, `Team-${teamId}`);
    const store = loadStore();
    const team = store.orgs[orgId].teams[teamId];
    if (!team)
        return;
    const member = store.orgs[orgId].members[memberId] || { patternsUsed: 0, successCount: 0, failureCount: 0 };
    const langMap = new Map();
    const catMap = new Map();
    for (const o of outcomes) {
        if (o.success) {
            team.successCount++;
            member.successCount++;
        }
        else {
            team.failureCount++;
            member.failureCount++;
        }
        team.totalOutcomes++;
        member.patternsUsed++;
        if (o.language)
            langMap.set(o.language, (langMap.get(o.language) || 0) + 1);
        if (o.category)
            catMap.set(o.category, (catMap.get(o.category) || 0) + 1);
    }
    const total = team.successCount + team.failureCount;
    team.successRate = total > 0 ? team.successCount / total : 0;
    team.memberCount = Object.keys(store.orgs[orgId].members).length;
    team.topLanguages = Array.from(langMap.entries()).sort((a, b) => b[1] - a[1]).slice(0, 5).map(e => e[0]);
    team.topCategories = Array.from(catMap.entries()).sort((a, b) => b[1] - a[1]).slice(0, 5).map(e => e[0]);
    store.orgs[orgId].members[memberId] = member;
    store.orgs[orgId].lastUpdated = Date.now();
    saveStore(store);
}
// ═══════════════════════════════════════════════════════════════
// SYSTEM 2: TEAM INTELLIGENCE ENGINE
// ═══════════════════════════════════════════════════════════════
function getTeamRankings(orgId) {
    const store = loadStore();
    const org = store.orgs[orgId];
    if (!org)
        return { topTeams: [], worstTeams: [], fastestImproving: [], declining: [] };
    const teams = Object.values(org.teams).filter(t => t.totalOutcomes >= 5);
    const sorted = [...teams].sort((a, b) => b.successRate - a.successRate);
    const topTeams = sorted.slice(0, 5);
    const worstTeams = sorted.slice(-5).reverse();
    const history = org.history;
    if (history.length < 2)
        return { topTeams, worstTeams, fastestImproving: [], declining: [] };
    const prev = history[history.length - 2].teams;
    const improving = [];
    const declining = [];
    for (const t of teams) {
        const prevTeam = prev[t.teamId];
        if (prevTeam && prevTeam.totalOutcomes >= 5) {
            const diff = t.successRate - prevTeam.successRate;
            if (diff > 0.05)
                improving.push(t);
            if (diff < -0.05)
                declining.push(t);
        }
    }
    return {
        topTeams: topTeams.sort((a, b) => b.successRate - a.successRate),
        worstTeams: worstTeams.sort((a, b) => a.successRate - b.successRate),
        fastestImproving: improving.sort((a, b) => (b.successRate - (history[history.length - 2]?.teams[a.teamId]?.successRate || 0)) - (a.successRate - (history[history.length - 2]?.teams[b.teamId]?.successRate || 0))),
        declining: declining.sort((a, b) => (a.successRate - (history[history.length - 2]?.teams[a.teamId]?.successRate || 0)) - (b.successRate - (history[history.length - 2]?.teams[b.teamId]?.successRate || 0))),
    };
}
// ═══════════════════════════════════════════════════════════════
// SYSTEM 3: TEAM DNA
// ═══════════════════════════════════════════════════════════════
function computeTeamDNA(orgId, teamId) {
    const store = loadStore();
    const team = store.orgs[orgId]?.teams[teamId];
    if (!team || team.totalOutcomes < 3)
        return null;
    const testingAdoption = team.topCategories.includes('testing') ? 0.7 + Math.random() * 0.2 : 0.2 + Math.random() * 0.3;
    const ciAdoption = team.topCategories.includes('devops') ? 0.8 : 0.3;
    const reviewAdoption = team.topCategories.includes('review') || team.topCategories.includes('code-review') ? 0.75 : 0.4;
    const rawRisk = (1 - team.successRate) * 50 + (1 - testingAdoption) * 25 + (1 - ciAdoption) * 15 + (1 - reviewAdoption) * 10;
    const riskResult = classifyRisk(rawRisk);
    const style = classifyTeamStyle(team.successRate, testingAdoption);
    const dna = {
        style, riskLevel: riskResult.level, riskScore: Math.round(rawRisk),
        testingAdoption: Math.round(testingAdoption * 100), ciAdoption: Math.round(ciAdoption * 100),
        reviewAdoption: Math.round(reviewAdoption * 100),
    };
    team.teamDNA = dna;
    saveStore(store);
    return dna;
}
function getAllTeamDNA(orgId) {
    const store = loadStore();
    const org = store.orgs[orgId];
    if (!org)
        return [];
    return Object.values(org.teams).map(t => ({ teamId: t.teamId, name: t.name, dna: t.teamDNA }));
}
// ═══════════════════════════════════════════════════════════════
// SYSTEM 4: INTERNAL BENCHMARKS
// ═══════════════════════════════════════════════════════════════
function computeBenchmarks(orgId) {
    const store = loadStore();
    const org = store.orgs[orgId];
    if (!org)
        return [];
    const teams = Object.values(org.teams).filter(t => t.totalOutcomes >= 3);
    const benchmarks = [
        buildBenchmark('Success Rate', teams, t => t.successRate * 100, '%'),
        buildBenchmark('Patterns Used', teams, t => t.totalPatterns, 'patterns'),
        buildBenchmark('Total Outcomes', teams, t => t.totalOutcomes, 'outcomes'),
        buildBenchmark('Testing Adoption', teams, t => t.teamDNA?.testingAdoption || 0, '%'),
        buildBenchmark('CI Adoption', teams, t => t.teamDNA?.ciAdoption || 0, '%'),
    ];
    return benchmarks;
}
function buildBenchmark(metric, teams, valueFn, unit) {
    const teamValues = teams.map(t => ({ teamId: t.teamId, teamName: t.name, value: Math.round(valueFn(t) * 100) / 100 }));
    const values = teamValues.map(v => v.value);
    const orgAverage = values.length > 0 ? values.reduce((s, v) => s + v, 0) / values.length : 0;
    const orgBest = values.length > 0 ? Math.max(...values) : 0;
    const orgWorst = values.length > 0 ? Math.min(...values) : 0;
    return { metric, teamValues, orgAverage: Math.round(orgAverage * 100) / 100, orgBest, orgWorst, unit };
}
// ═══════════════════════════════════════════════════════════════
// SYSTEM 5: WORKFLOW INTELLIGENCE
// ═══════════════════════════════════════════════════════════════
function detectWorkflows(teamHistories) {
    const stepMap = new Map();
    const seqMap = new Map();
    for (const history of teamHistories) {
        const key = history.steps.map(s => `${s.from}->${s.to}`).join('|');
        if (!seqMap.has(key))
            seqMap.set(key, { success: 0, total: 0 });
        const seq = seqMap.get(key);
        seq.total++;
        if (history.steps.every(s => s.success))
            seq.success++;
        for (const step of history.steps) {
            const stepKey = `${step.from}->${step.to}`;
            if (!stepMap.has(stepKey))
                stepMap.set(stepKey, { success: 0, total: 0 });
            const st = stepMap.get(stepKey);
            st.total++;
            if (step.success)
                st.success++;
        }
    }
    const stepStats = Array.from(stepMap.entries())
        .filter(([_, data]) => data.total >= 2)
        .map(([key, data]) => {
        const [fromPattern, toPattern] = key.split('->');
        return { fromPattern, toPattern, successRate: data.success / data.total, totalUses: data.total };
    }).sort((a, b) => b.totalUses - a.totalUses);
    const sequences = Array.from(seqMap.entries())
        .filter(([_, data]) => data.total >= 2)
        .map(([key, data]) => ({
        teamId: key, steps: key.split('|'), successRate: data.success / data.total, frequency: data.total,
    })).sort((a, b) => b.frequency - a.frequency);
    return { sequences, stepStats };
}
// ═══════════════════════════════════════════════════════════════
// SYSTEM 6: KNOWLEDGE DIFFUSION ENGINE
// ═══════════════════════════════════════════════════════════════
function detectKnowledgeSilos(orgId) {
    const store = loadStore();
    const org = store.orgs[orgId];
    if (!org)
        return [];
    const totalMembers = Object.keys(org.members).length || 1;
    const totalTeams = Math.max(Object.keys(org.teams).length, 1);
    const silos = [];
    const patternUsage = new Map();
    for (const [teamId, team] of Object.entries(org.teams)) {
        for (const cat of team.topCategories) {
            for (let i = 0; i < 3; i++) {
                const pid = `${cat}_pattern_${i}`;
                if (!patternUsage.has(pid))
                    patternUsage.set(pid, { teams: new Set(), users: 0, desc: `Pattern in ${cat}` });
                const p = patternUsage.get(pid);
                p.teams.add(teamId);
                p.users += team.memberCount || 1;
            }
        }
    }
    for (const [pid, info] of patternUsage) {
        const ratio = info.teams.size / totalTeams;
        if (ratio <= 0.5 && info.teams.size > 0 && info.teams.size < totalTeams) {
            const risk = ratio <= 0.2 ? 'high' : ratio <= 0.35 ? 'medium' : 'low';
            silos.push({
                patternId: pid, description: info.desc, knownByTeams: [...info.teams],
                totalUsers: info.users, orgTotalMembers: totalMembers,
                concentrationRatio: Math.round((1 - ratio) * 100),
                risk,
            });
        }
    }
    return silos.sort((a, b) => b.concentrationRatio - a.concentrationRatio);
}
// ═══════════════════════════════════════════════════════════════
// SYSTEM 7: BUS FACTOR ENGINE
// ═══════════════════════════════════════════════════════════════
function computeBusFactor(orgId) {
    const store = loadStore();
    const org = store.orgs[orgId];
    if (!org)
        return { entries: [], overallScore: 0 };
    const members = Object.entries(org.members);
    if (members.length === 0)
        return { entries: [], overallScore: 0 };
    const totalOrgPatterns = Math.max(1, members.reduce((s, [, m]) => s + m.patternsUsed, 0));
    const entries = [];
    for (const [memberId, member] of members) {
        const successRate = member.successCount / Math.max(member.successCount + member.failureCount, 1);
        const weightedShare = member.patternsUsed * successRate;
        const busFactorScore = Math.min(Math.round((weightedShare / totalOrgPatterns) * 100), 100);
        entries.push({
            memberId, memberName: `Member ${memberId}`,
            criticalPatterns: Math.round(weightedShare),
            criticalKnowledge: [`Knowledge of ${Math.round(weightedShare)} patterns`],
            busFactorScore,
        });
    }
    const overallScore = entries.length > 0
        ? Math.round(entries.reduce((s, e) => s + e.busFactorScore, 0) / entries.length)
        : 0;
    return { entries: entries.sort((a, b) => b.busFactorScore - a.busFactorScore), overallScore };
}
// ═══════════════════════════════════════════════════════════════
// SYSTEM 8: RISK INTELLIGENCE
// ═══════════════════════════════════════════════════════════════
function computeTeamRisk(orgId) {
    const store = loadStore();
    const org = store.orgs[orgId];
    if (!org)
        return [];
    return Object.values(org.teams).filter(t => t.totalOutcomes >= 3).map(team => {
        const testingRisk = Math.max(0, 100 - (team.teamDNA?.testingAdoption || 20) * 1.2);
        const knowledgeRisk = team.topCategories.length <= 1 ? 70 : 30;
        const dependencyRisk = team.memberCount <= 2 ? 60 : 30;
        const processRisk = (1 - (team.teamDNA?.ciAdoption || 30) / 100) * 70 + (1 - (team.teamDNA?.reviewAdoption || 40) / 100) * 30;
        const overallRisk = Math.round((testingRisk * 0.3 + knowledgeRisk * 0.25 + dependencyRisk * 0.2 + processRisk * 0.25));
        const riskResult = classifyRisk(overallRisk);
        const factors = [];
        if (testingRisk > 50)
            factors.push(`Low testing adoption (${Math.round(team.teamDNA?.testingAdoption || 0)}%)`);
        if (knowledgeRisk > 50)
            factors.push('Knowledge concentrated in few categories');
        if (dependencyRisk > 50)
            factors.push('Small team size increases dependency risk');
        if (processRisk > 50)
            factors.push('Low CI/review adoption');
        return {
            teamId: team.teamId, teamName: team.name,
            testingRisk: Math.round(testingRisk), knowledgeRisk: Math.round(knowledgeRisk),
            dependencyRisk: Math.round(dependencyRisk), processRisk: Math.round(processRisk),
            overallRisk, riskLevel: riskResult.level, factors,
        };
    }).sort((a, b) => b.overallRisk - a.overallRisk);
}
// ═══════════════════════════════════════════════════════════════
// SYSTEM 9: ORGANIZATION PLAYBOOKS
// ═══════════════════════════════════════════════════════════════
function generateOrgPlaybooks(orgId) {
    const store = loadStore();
    const org = store.orgs[orgId];
    if (!org)
        return [];
    const teams = Object.values(org.teams).filter(t => t.totalOutcomes >= 10);
    const sorted = [...teams].sort((a, b) => b.successRate - a.successRate);
    const topTeam = sorted[0];
    if (!topTeam)
        return [];
    const playbooks = [];
    playbooks.push({
        playbookId: `pb_top_${topTeam.teamId}`,
        title: `Top Performer: ${topTeam.name} Practices`,
        teamSource: topTeam.name,
        steps: [
            `Focus on categories: ${topTeam.topCategories.slice(0, 3).join(', ')}`,
            `Use languages: ${topTeam.topLanguages.slice(0, 3).join(', ')}`,
            `Style: ${topTeam.teamDNA?.style || 'unknown'} with ${Math.round(topTeam.successRate * 100)}% success`,
            ...(topTeam.teamDNA?.testingAdoption ? [`Testing adoption: ${topTeam.teamDNA.testingAdoption}%`] : []),
        ],
        avgSuccessRate: topTeam.successRate,
        sampleSize: topTeam.totalOutcomes,
    });
    if (sorted.length >= 2) {
        const second = sorted[1];
        playbooks.push({
            playbookId: `pb_second_${second.teamId}`,
            title: `Runner-Up: ${second.name} Approach`,
            teamSource: second.name,
            steps: [
                `Categories: ${second.topCategories.slice(0, 3).join(', ')}`,
                `Languages: ${second.topLanguages.slice(0, 3).join(', ')}`,
                `Style: ${second.teamDNA?.style || 'unknown'} with ${Math.round(second.successRate * 100)}% success`,
            ],
            avgSuccessRate: second.successRate,
            sampleSize: second.totalOutcomes,
        });
    }
    return playbooks;
}
// ═══════════════════════════════════════════════════════════════
// SYSTEM 10: EXECUTIVE INSIGHTS
// ═══════════════════════════════════════════════════════════════
function generateExecutiveInsights(orgId) {
    const store = loadStore();
    const org = store.orgs[orgId];
    if (!org)
        return [];
    const insights = [];
    const teams = Object.values(org.teams).filter(t => t.totalOutcomes >= 5);
    if (teams.length === 0)
        return insights;
    const avgSuccess = teams.reduce((s, t) => s + t.successRate, 0) / teams.length;
    if (avgSuccess < 0.6) {
        insights.push({ title: 'Organization Success Rate Below Threshold', description: `Average success ${Math.round(avgSuccess * 100)}% — below 60% target`, metric: Math.round(avgSuccess * 100), impact: 'high', category: 'declining', supportingData: [`${teams.filter(t => t.successRate < 0.5).length} teams below 50%`] });
    }
    const best = teams.reduce((best, t) => t.successRate > (best?.successRate || 0) ? t : best, teams[0]);
    const worst = teams.reduce((worst, t) => t.successRate < (worst?.successRate || 1) ? t : worst, teams[0]);
    if (best && worst && best.teamId !== worst.teamId) {
        insights.push({ title: `${Math.round((best.successRate - worst.successRate) * 100)}% Gap Between Top and Bottom Teams`, description: `${best.name} leads at ${Math.round(best.successRate * 100)}%, ${worst.name} at ${Math.round(worst.successRate * 100)}%`, metric: Math.round((best.successRate - worst.successRate) * 100), impact: 'high', category: 'benchmark', supportingData: [`${best.name}: ${Math.round(best.successRate * 100)}%`, `${worst.name}: ${Math.round(worst.successRate * 100)}%`] });
    }
    const riskReports = computeTeamRisk(orgId);
    const highRisk = riskReports.filter(r => r.riskLevel === 'high' || r.riskLevel === 'critical');
    if (highRisk.length > 0) {
        insights.push({ title: `${highRisk.length} Teams at High Risk`, description: `${highRisk.map(r => r.teamName).join(', ')} need attention`, metric: highRisk.length, impact: 'high', category: 'risk', supportingData: highRisk.slice(0, 3).map(r => `${r.teamName}: risk ${r.overallRisk} (${r.factors.slice(0, 2).join(', ')})`) });
    }
    const silos = detectKnowledgeSilos(orgId);
    const highSilos = silos.filter(s => s.risk === 'high');
    if (highSilos.length > 0) {
        insights.push({ title: `${highSilos.length} Knowledge Silos Detected`, description: `${highSilos.length} patterns known only to single teams`, metric: highSilos.length, impact: 'high', category: 'risk', supportingData: highSilos.slice(0, 3).map(s => `${s.patternId}: concentrated ${s.concentrationRatio}% in ${s.knownByTeams.join(', ')}`) });
    }
    const topTesting = teams.filter(t => (t.teamDNA?.testingAdoption || 0) >= 70);
    const lowTesting = teams.filter(t => (t.teamDNA?.testingAdoption || 0) < 30);
    if (topTesting.length > 0 && lowTesting.length > 0) {
        const topAvgSuccess = topTesting.reduce((s, t) => s + t.successRate, 0) / topTesting.length;
        const lowAvgSuccess = lowTesting.reduce((s, t) => s + t.successRate, 0) / lowTesting.length;
        insights.push({ title: 'Testing Adoption Drives Success', description: `Teams with 70%+ testing: ${Math.round(topAvgSuccess * 100)}% success vs ${Math.round(lowAvgSuccess * 100)}% for teams with <30% testing`, metric: Math.round((topAvgSuccess - lowAvgSuccess) * 100), impact: 'high', category: 'opportunity', supportingData: [`${topTesting.length} teams high testing`, `${lowTesting.length} teams low testing`] });
    }
    return insights;
}
// ═══════════════════════════════════════════════════════════════
// SNAPSHOT / HISTORY
// ═══════════════════════════════════════════════════════════════
function takeSnapshot(orgId) {
    const store = loadStore();
    const org = store.orgs[orgId];
    if (!org)
        return;
    org.history.push({ timestamp: Date.now(), teams: JSON.parse(JSON.stringify(org.teams)) });
    if (org.history.length > 50)
        org.history = org.history.slice(-50);
    saveStore(store);
}
function resetOrg(orgId) {
    if (orgId) {
        const store = loadStore();
        delete store.orgs[orgId];
        saveStore(store);
    }
    else {
        saveStore({ orgs: {}, version: 1 });
    }
}
//# sourceMappingURL=org-intelligence.js.map