"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.buildKnowledgeGraph = buildKnowledgeGraph;
exports.getKnowledgeGraph = getKnowledgeGraph;
exports.getNodeNeighbors = getNodeNeighbors;
exports.findRelatedPatterns = findRelatedPatterns;
exports.getGraphStats = getGraphStats;
exports.extractEntities = extractEntities;
exports.inferRelationships = inferRelationships;
exports.findPaths = findPaths;
exports.addNodes = addNodes;
exports.addNode = addNode;
exports.removeNode = removeNode;
exports.addRelationships = addRelationships;
exports.addRelationship = addRelationship;
exports.getNodeEdges = getNodeEdges;
exports.getNodesByType = getNodesByType;
exports.computeInfluence = computeInfluence;
exports.detectDependencies = detectDependencies;
exports.detectConflicts = detectConflicts;
exports.detectSequences = detectSequences;
exports.computeOutcomeCorrelations = computeOutcomeCorrelations;
exports.linkProjectDNA = linkProjectDNA;
exports.buildCommunityGraph = buildCommunityGraph;
exports.getCommunityInsights = getCommunityInsights;
exports.discoverPaths = discoverPaths;
exports.getGraphVersion = getGraphVersion;
exports.resetGraph = resetGraph;
exports.exportGraphJSON = exportGraphJSON;
exports.importGraphJSON = importGraphJSON;
exports.ensureCloudGraphTable = ensureCloudGraphTable;
exports.recordCloudEntity = recordCloudEntity;
exports.getCloudEntities = getCloudEntities;
exports.recordCloudRelationship = recordCloudRelationship;
exports.getCloudRelationships = getCloudRelationships;
exports.getCloudPathTraversal = getCloudPathTraversal;
exports.getCloudNodeNeighbors = getCloudNodeNeighbors;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const os = __importStar(require("os"));
// ═══════════════════════════════════════════════════════════════
// STORAGE
// ═══════════════════════════════════════════════════════════════
const GRAPH_PATH = path.join(os.homedir(), '.fivo', 'cell', 'knowledge-graph.json');
const GRAPH_STORE_PATH = path.join(os.homedir(), '.fivo', 'cell', 'knowledge-graph-store.json');
const DEFAULT_GRAPH = { nodes: [], edges: [], builtAt: 0, version: 0 };
let graph = { ...DEFAULT_GRAPH };
function ensureDir() {
    const dir = path.dirname(GRAPH_PATH);
    if (!fs.existsSync(dir))
        fs.mkdirSync(dir, { recursive: true });
}
function saveGraph() {
    ensureDir();
    try {
        fs.writeFileSync(GRAPH_PATH, JSON.stringify(graph, null, 2), 'utf-8');
    }
    catch { }
}
function loadGraph() {
    ensureDir();
    try {
        if (fs.existsSync(GRAPH_PATH)) {
            graph = JSON.parse(fs.readFileSync(GRAPH_PATH, 'utf-8'));
        }
    }
    catch {
        graph = { ...DEFAULT_GRAPH };
    }
}
function loadStore() {
    ensureDir();
    try {
        if (fs.existsSync(GRAPH_STORE_PATH)) {
            return JSON.parse(fs.readFileSync(GRAPH_STORE_PATH, 'utf-8'));
        }
    }
    catch { }
    return { graphs: {}, versions: [], lastGraphId: '' };
}
function saveStore(data) {
    ensureDir();
    fs.writeFileSync(GRAPH_STORE_PATH, JSON.stringify(data, null, 2), 'utf-8');
}
// ═══════════════════════════════════════════════════════════════
// HELPERS
// ═══════════════════════════════════════════════════════════════
function tokenize(text) {
    return text.toLowerCase().replace(/[^a-z0-9_]/g, ' ').split(/\s+/).filter(Boolean);
}
function edgeKey(a, b, type) {
    return `${a}|${b}|${type}`;
}
function upsertNode(id, type, label, weight = 1, metadata) {
    const existing = graph.nodes.find(n => n.id === id);
    if (existing) {
        existing.weight += weight;
        if (metadata)
            existing.metadata = { ...existing.metadata, ...metadata };
    }
    else {
        graph.nodes.push({ id, type, label, weight, metadata });
    }
}
function upsertEdge(from, to, type, weight, metadata) {
    const key = edgeKey(from, to, type);
    const existing = graph.edges.find(e => edgeKey(e.from, e.to, e.type) === key);
    if (existing) {
        existing.weight = (existing.weight + weight) / 2;
        if (metadata)
            existing.metadata = { ...existing.metadata, ...metadata };
    }
    else {
        graph.edges.push({ from, to, type, weight, metadata });
    }
}
// ═══════════════════════════════════════════════════════════════
// LEGACY API (backward compat)
// ═══════════════════════════════════════════════════════════════
function buildKnowledgeGraph(patterns) {
    loadGraph();
    graph.nodes = [];
    graph.edges = [];
    graph.builtAt = Date.now();
    graph.version = (graph.version || 0) + 1;
    for (const p of patterns) {
        upsertNode(p.patternId, 'pattern', p.description);
        const catId = `cat:${p.category}`;
        upsertNode(catId, 'category', p.category);
        upsertEdge(p.patternId, catId, 'category_of', 1);
        if (p.language && p.language !== 'unknown') {
            const langId = `lang:${p.language}`;
            upsertNode(langId, 'language', p.language);
        }
        if (p.framework && p.framework !== 'unknown') {
            const fwId = `fw:${p.framework}`;
            upsertNode(fwId, 'framework', p.framework);
        }
        if (p.conditions) {
            for (const c of p.conditions) {
                if (c.type === 'language')
                    upsertNode(`lang:${c.value}`, 'language', c.value);
                if (c.type === 'framework')
                    upsertNode(`fw:${c.value}`, 'framework', c.value);
            }
        }
    }
    const patternArr = patterns;
    for (let i = 0; i < patternArr.length; i++) {
        for (let j = i + 1; j < patternArr.length; j++) {
            const a = patternArr[i];
            const b = patternArr[j];
            const tokensA = new Set([...tokenize(a.from), ...tokenize(a.to)]);
            const tokensB = new Set([...tokenize(b.from), ...tokenize(b.to)]);
            const intersection = new Set([...tokensA].filter(t => tokensB.has(t)));
            const union = new Set([...tokensA, ...tokensB]);
            const jaccard = union.size > 0 ? intersection.size / union.size : 0;
            if (jaccard >= 0.3) {
                upsertEdge(a.patternId, b.patternId, 'similar', Math.round(jaccard * 10) / 10);
            }
        }
    }
    saveGraph();
    return graph;
}
function getKnowledgeGraph() {
    if (graph.nodes.length === 0)
        loadGraph();
    return graph;
}
function getNodeNeighbors(nodeId, maxDepth = 1) {
    const g = getKnowledgeGraph();
    const node = g.nodes.find(n => n.id === nodeId);
    if (!node)
        return null;
    if (maxDepth <= 1) {
        return { node, edges: g.edges.filter(e => e.from === nodeId || e.to === nodeId) };
    }
    const visited = new Set([nodeId]);
    const edges = [];
    let currentLevel = new Set([nodeId]);
    for (let depth = 0; depth < maxDepth; depth++) {
        const nextLevel = new Set();
        for (const cur of currentLevel) {
            for (const e of g.edges) {
                if (e.from === cur && !visited.has(e.to)) {
                    visited.add(e.to);
                    nextLevel.add(e.to);
                    edges.push(e);
                }
                else if (e.to === cur && !visited.has(e.from)) {
                    visited.add(e.from);
                    nextLevel.add(e.from);
                    edges.push(e);
                }
            }
        }
        if (nextLevel.size === 0)
            break;
        currentLevel = nextLevel;
    }
    return { node, edges };
}
function findRelatedPatterns(patternId, limit = 10) {
    const g = getKnowledgeGraph();
    const edges = g.edges.filter(e => (e.from === patternId || e.to === patternId) && e.type !== 'category_of' && e.type !== 'language_of');
    const related = new Map();
    for (const e of edges) {
        const relatedId = e.from === patternId ? e.to : e.from;
        if (!related.has(relatedId) || related.get(relatedId).weight < e.weight) {
            related.set(relatedId, { relationship: e.type, weight: e.weight });
        }
    }
    return Array.from(related.entries()).sort((a, b) => b[1].weight - a[1].weight).slice(0, limit)
        .map(([pid, info]) => ({ patternId: pid, relationship: info.relationship, weight: info.weight }));
}
function getGraphStats() {
    const g = getKnowledgeGraph();
    return {
        nodes: g.nodes.length, edges: g.edges.length, builtAt: g.builtAt, version: g.version,
        patternNodes: g.nodes.filter(n => n.type === 'pattern').length,
        categoryNodes: g.nodes.filter(n => n.type === 'category').length,
        languageNodes: g.nodes.filter(n => n.type === 'language').length,
    };
}
function extractEntities(patterns) {
    const entityMap = new Map();
    for (const p of patterns) {
        const all = `${p.from} ${p.to} ${p.description} ${p.category}`;
        const words = all.split(/[^a-zA-Z]/).filter(w => w.length >= 3);
        const classes = words.filter(w => /^[A-Z][a-z]+[A-Z]/.test(w));
        for (const c of classes) {
            if (!entityMap.has(c))
                entityMap.set(c, { type: 'class', patterns: new Set() });
            entityMap.get(c).patterns.add(p.patternId);
        }
        if (p.to.includes('=>') || p.to.startsWith('function') || p.from.startsWith('function')) {
            const fName = 'fn:' + p.category;
            if (!entityMap.has(fName))
                entityMap.set(fName, { type: 'function', patterns: new Set() });
            entityMap.get(fName).patterns.add(p.patternId);
        }
        const vars = words.filter(w => /^[a-z][a-zA-Z0-9]{2,}$/.test(w) && !['const', 'let', 'var', 'function', 'return', 'import', 'export', 'class', 'from', 'this', 'true', 'false', 'null', 'undefined'].includes(w));
        for (const v of vars.slice(0, 5)) {
            const key = `var:${v}`;
            if (!entityMap.has(key))
                entityMap.set(key, { type: 'variable', patterns: new Set() });
            entityMap.get(key).patterns.add(p.patternId);
        }
        const fws = ['react', 'vue', 'angular', 'express', 'django', 'spring', 'next', 'nuxt', 'svelte', 'tailwind', 'redux', 'graphql', 'jest', 'mocha'];
        for (const fw of fws) {
            if (all.toLowerCase().includes(fw)) {
                if (!entityMap.has(fw))
                    entityMap.set(fw, { type: 'framework', patterns: new Set() });
                entityMap.get(fw).patterns.add(p.patternId);
            }
        }
    }
    return Array.from(entityMap.entries())
        .map(([name, data]) => ({ name, type: data.type, occurrences: data.patterns.size, patterns: Array.from(data.patterns) }))
        .sort((a, b) => b.occurrences - a.occurrences);
}
function inferRelationships(patterns) {
    const rels = [];
    for (let i = 0; i < patterns.length; i++) {
        for (let j = i + 1; j < patterns.length; j++) {
            const a = patterns[i];
            const b = patterns[j];
            if (a.category === b.category)
                rels.push({ from: a.patternId, to: b.patternId, type: 'similar_to', strength: 0.6, evidence: [`Both in ${a.category} category`] });
            if (a.to.includes(b.from) || b.to.includes(a.from))
                rels.push({ from: a.patternId, to: b.patternId, type: 'prerequisite', strength: 0.8, evidence: [`"${a.to}" leads to "${b.from}"`] });
            if (a.from === b.from && a.to !== b.to)
                rels.push({ from: a.patternId, to: b.patternId, type: 'alternative_to', strength: 0.7, evidence: [`Both transform "${a.from}"`] });
            if (a.from === b.to && a.to === b.from)
                rels.push({ from: a.patternId, to: b.patternId, type: 'conflicts_with', strength: 0.9, evidence: [`"${a.description}" reverses "${b.description}"`] });
        }
    }
    return rels;
}
function findPaths(from, to, maxDepth = 4) {
    const g = getKnowledgeGraph();
    const results = [];
    function dfs(current, target, visited, pathEdges, depth) {
        if (depth > maxDepth)
            return;
        if (current === target && pathEdges.length > 0) {
            const nodes = [pathEdges[0].from];
            for (const e of pathEdges)
                nodes.push(e.to);
            results.push({ nodes, edges: pathEdges.map(e => e.type), totalWeight: pathEdges.reduce((s, e) => s + e.weight, 0) });
            return;
        }
        const neighbors = g.edges.filter(e => e.from === current || e.to === current);
        for (const edge of neighbors) {
            const next = edge.from === current ? edge.to : edge.from;
            if (!visited.has(next)) {
                visited.add(next);
                pathEdges.push(edge);
                dfs(next, target, visited, pathEdges, depth + 1);
                pathEdges.pop();
                visited.delete(next);
            }
        }
    }
    dfs(from, to, new Set([from]), [], 0);
    return results.sort((a, b) => b.totalWeight - a.totalWeight);
}
function addNodes(inputs) {
    loadGraph();
    for (const inp of inputs) {
        upsertNode(inp.id, inp.type, inp.label, inp.weight || 1, { ...inp.metadata, source: inp.source || 'pattern' });
    }
    saveGraph();
}
function addNode(input) {
    addNodes([input]);
}
function removeNode(nodeId) {
    loadGraph();
    const idx = graph.nodes.findIndex(n => n.id === nodeId);
    if (idx === -1)
        return false;
    graph.nodes.splice(idx, 1);
    graph.edges = graph.edges.filter(e => e.from !== nodeId && e.to !== nodeId);
    saveGraph();
    return true;
}
function addRelationships(inputs) {
    loadGraph();
    for (const inp of inputs) {
        upsertEdge(inp.from, inp.to, inp.type, inp.weight, inp.evidence ? { evidence: inp.evidence } : undefined);
    }
    saveGraph();
}
function addRelationship(input) {
    addRelationships([input]);
}
function getNodeEdges(nodeId) {
    const g = getKnowledgeGraph();
    return g.edges.filter(e => e.from === nodeId || e.to === nodeId);
}
function getNodesByType(type) {
    return getKnowledgeGraph().nodes.filter(n => n.type === type);
}
// ─── SYSTEM 3: INFLUENCE ENGINE ──────────────────────
function computeInfluence(patternOutcomes) {
    const g = getKnowledgeGraph();
    const scores = [];
    for (const node of g.nodes) {
        if (node.type === 'pattern' && patternOutcomes.has(node.id)) {
            const outcome = patternOutcomes.get(node.id);
            // Count how many other patterns link to this one
            const incomingEdges = g.edges.filter(e => e.to === node.id);
            const outgoingEdges = g.edges.filter(e => e.from === node.id);
            const connectedness = incomingEdges.length + outgoingEdges.length;
            const outcomeScore = outcome.successRate * (outcome.usageCount / Math.max(outcome.usageCount, 10));
            const influence = Math.round((connectedness * 0.3 + outcomeScore * 0.7) * 100) / 100;
            const evidence = [];
            if (incomingEdges.length > 0)
                evidence.push(`${incomingEdges.length} incoming relationships`);
            if (outgoingEdges.length > 0)
                evidence.push(`${outgoingEdges.length} outgoing relationships`);
            evidence.push(`Success rate: ${outcome.successRate}, Usage: ${outcome.usageCount}`);
            scores.push({ nodeId: node.id, label: node.label, score: influence, evidence });
        }
    }
    return scores.sort((a, b) => b.score - a.score);
}
// ─── SYSTEM 4: DEPENDENCY ENGINE ─────────────────────
function detectDependencies(patterns) {
    const rels = [];
    const all = patterns;
    for (let i = 0; i < all.length; i++) {
        for (let j = 0; j < all.length; j++) {
            if (i === j)
                continue;
            const a = all[i];
            const b = all[j];
            // If A's "to" transformation is a prerequisite for B's "from"
            if (a.to && b.from && a.to.includes(b.from)) {
                rels.push({ from: a.patternId, to: b.patternId, type: 'depends_on', weight: 0.8, evidence: [`"${a.to}" contains "${b.from}"`] });
            }
            // Same category co-occurrence indicates dependency
            if (a.category === b.category && a.category !== 'general') {
                rels.push({ from: a.patternId, to: b.patternId, type: 'related_to', weight: 0.5, evidence: [`Both in ${a.category}`] });
            }
        }
    }
    return rels;
}
// ─── SYSTEM 5: CONFLICT ENGINE ───────────────────────
function detectConflicts(patterns) {
    const rels = [];
    for (let i = 0; i < patterns.length; i++) {
        for (let j = i + 1; j < patterns.length; j++) {
            const a = patterns[i];
            const b = patterns[j];
            if (a.from && b.to && a.to && b.from && a.from === b.to && a.to === b.from) {
                rels.push({ from: a.patternId, to: b.patternId, type: 'conflicts', weight: 0.9, evidence: [`"${a.description}" reverses "${b.description}"`] });
            }
            // Different categories with different goals
            if (a.category !== b.category && (a.description.includes('microservice') && b.description.includes('monolith'))) {
                rels.push({ from: a.patternId, to: b.patternId, type: 'conflicts', weight: 0.7, evidence: ['Architecture conflict'] });
            }
        }
    }
    return rels;
}
// ─── SYSTEM 6: SEQUENCE ENGINE ───────────────────────
function detectSequences(developerHistories) {
    const pairCount = new Map();
    for (const history of developerHistories) {
        const sorted = [...history].sort((a, b) => a.timestamp - b.timestamp);
        for (let i = 0; i < sorted.length - 1; i++) {
            for (let j = i + 1; j < Math.min(i + 5, sorted.length); j++) {
                const key = `${sorted[i].patternId}|${sorted[j].patternId}`;
                const timeGap = sorted[j].timestamp - sorted[i].timestamp;
                const weight = timeGap > 0 ? Math.max(0.1, 1 - (timeGap / 86400000)) : 0.5;
                if (!pairCount.has(key))
                    pairCount.set(key, { count: 0, weight: 0 });
                const entry = pairCount.get(key);
                entry.count++;
                entry.weight = Math.max(entry.weight, weight);
            }
        }
    }
    const rels = [];
    for (const [key, data] of pairCount) {
        if (data.count >= 2) {
            const [from, to] = key.split('|');
            rels.push({ from, to, type: 'sequenced_after', weight: Math.round((data.weight * Math.min(data.count / 5, 1)) * 100) / 100, evidence: [`Sequence seen ${data.count} times`] });
        }
    }
    return rels;
}
// ─── SYSTEM 7: OUTCOME CORRELATION ───────────────────
function computeOutcomeCorrelations(allOutcomes) {
    const correlations = [];
    const entries = Array.from(allOutcomes.entries());
    for (let i = 0; i < entries.length; i++) {
        for (let j = i + 1; j < entries.length; j++) {
            const [pidA, outA] = entries[i];
            const [pidB, outB] = entries[j];
            if (outA.usageCount < 3 || outB.usageCount < 3)
                continue;
            const diff = outA.successRate - outB.successRate;
            const direction = Math.abs(diff) < 0.1 ? 'neutral' : diff > 0 ? 'positive' : 'negative';
            const sampleSize = Math.min(outA.usageCount, outB.usageCount);
            correlations.push({
                fromPattern: pidA, toPattern: pidB,
                correlation: Math.round(Math.abs(diff) * 100) / 100,
                sampleSize, direction,
                evidence: [`${pidA}: ${outA.successRate} success (${outA.usageCount} uses)`, `${pidB}: ${outB.successRate} success (${outB.usageCount} uses)`],
            });
        }
    }
    return correlations.sort((a, b) => b.correlation - a.correlation);
}
// ─── SYSTEM 8: PROJECT DNA LINKS ─────────────────────
function linkProjectDNA(dnaFingerprint, patternIds) {
    const rels = [];
    const prefix = `dna:`;
    const fpId = `${prefix}fingerprint`;
    upsertNode(fpId, 'dna_fingerprint', `DNA: ${dnaFingerprint.primaryLanguage}`, 1, { ...dnaFingerprint });
    const archId = `${prefix}arch:${dnaFingerprint.architecture}`;
    upsertNode(archId, 'project_dna', `Architecture: ${dnaFingerprint.architecture}`);
    rels.push({ from: fpId, to: archId, type: 'belongs_to', weight: 1, evidence: ['DNA fingerprint'] });
    const langId = `${prefix}lang:${dnaFingerprint.primaryLanguage}`;
    const existingLang = graph.nodes.find(n => n.id === `lang:${dnaFingerprint.primaryLanguage}`);
    if (existingLang) {
        rels.push({ from: fpId, to: existingLang.id, type: 'uses', weight: 1, evidence: ['Primary language'] });
    }
    for (const pid of patternIds) {
        const pNode = graph.nodes.find(n => n.id === pid);
        if (pNode) {
            rels.push({ from: fpId, to: pid, type: 'related_to', weight: 0.8, evidence: ['DNA-to-pattern link'] });
            if (dnaFingerprint.architecture === 'layered' || dnaFingerprint.architecture === 'mvc') {
                rels.push({ from: pid, to: archId, type: 'belongs_to', weight: 0.6, evidence: [`Pattern used in ${dnaFingerprint.architecture}`] });
            }
        }
    }
    return rels;
}
// ─── SYSTEM 9: COMMUNITY GRAPH ───────────────────────
function buildCommunityGraph(allProfiles) {
    const langFreq = new Map();
    const catFreq = new Map();
    let totalDevs = allProfiles.length || 1;
    for (const prof of allProfiles) {
        for (const [lang, count] of Object.entries(prof.languages)) {
            langFreq.set(lang, (langFreq.get(lang) || 0) + count);
        }
        for (const cat of prof.topCategories) {
            catFreq.set(cat, (catFreq.get(cat) || 0) + 1);
        }
    }
    const nodes = [];
    const edges = [];
    // Community concept nodes for languages
    for (const [lang, freq] of langFreq) {
        const pct = Math.round((freq / totalDevs) * 100);
        nodes.push({ id: `community:lang:${lang}`, type: 'community_concept', label: `Community: ${lang}`, weight: pct });
    }
    // Community concept nodes for categories
    for (const [cat, freq] of catFreq) {
        const pct = Math.round((freq / totalDevs) * 100);
        nodes.push({ id: `community:cat:${cat}`, type: 'community_concept', label: `Community: ${cat}`, weight: pct });
    }
    // Link community nodes to existing language/category nodes
    for (const lang of langFreq.keys()) {
        edges.push({ from: `community:lang:${lang}`, to: `lang:${lang}`, type: 'related_to', weight: 0.7 });
    }
    for (const cat of catFreq.keys()) {
        edges.push({ from: `community:cat:${cat}`, to: `cat:${cat}`, type: 'related_to', weight: 0.7 });
    }
    return { nodes, edges };
}
function getCommunityInsights() {
    const g = getKnowledgeGraph();
    const communityNodes = g.nodes.filter(n => n.type === 'community_concept');
    return communityNodes.map(n => {
        const edges = g.edges.filter(e => e.from === n.id || e.to === n.id);
        const topPats = edges.filter(e => {
            const other = e.from === n.id ? e.to : e.from;
            return g.nodes.find(gn => gn.id === other && gn.type === 'pattern');
        }).slice(0, 5).map(e => e.from === n.id ? e.to : e.from);
        return {
            concept: n.label, developerCount: n.weight * 10, patternCount: edges.length,
            topPatterns: topPats, avgSuccessRate: 0.75,
        };
    });
}
// ─── SYSTEM 10: PATH DISCOVERY ───────────────────────
function discoverPaths(fromNode, toNode, maxDepth = 5) {
    const g = getKnowledgeGraph();
    const results = [];
    function dfs(current, target, visited, pathEdges, depth) {
        if (depth > maxDepth)
            return;
        if (current === target && pathEdges.length > 0) {
            const nodes = [pathEdges[0].from];
            const nodeLabels = [];
            for (const e of pathEdges) {
                nodes.push(e.to);
                const toNode = g.nodes.find(n => n.id === e.to);
                nodeLabels.push(toNode?.label || e.to);
            }
            const firstNode = g.nodes.find(n => n.id === pathEdges[0].from);
            nodeLabels.unshift(firstNode?.label || pathEdges[0].from);
            results.push({
                nodes, edges: pathEdges.map(e => `${e.type}`), totalWeight: pathEdges.reduce((s, e) => s + e.weight, 0),
                nodeLabels, edgeTypes: pathEdges.map(e => e.type),
            });
            return;
        }
        const neighbors = g.edges.filter(e => e.from === current || e.to === current);
        for (const edge of neighbors) {
            const next = edge.from === current ? edge.to : edge.from;
            if (!visited.has(next) || next === target) {
                visited.add(next);
                pathEdges.push(edge);
                dfs(next, target, visited, pathEdges, depth + 1);
                pathEdges.pop();
            }
        }
    }
    dfs(fromNode, toNode, new Set([fromNode]), [], 0);
    return results.sort((a, b) => b.totalWeight - a.totalWeight);
}
// ─── GRAPH EVOLUTION & HISTORY ──────────────────────
function getGraphVersion() {
    return graph.version || 0;
}
function resetGraph() {
    graph = { ...DEFAULT_GRAPH, version: graph.version + 1 };
    saveGraph();
}
function exportGraphJSON() {
    return JSON.stringify(getKnowledgeGraph(), null, 2);
}
function importGraphJSON(json) {
    try {
        const parsed = JSON.parse(json);
        if (parsed.nodes && parsed.edges) {
            graph = parsed;
            saveGraph();
        }
    }
    catch { }
}
// ─── CLOUD GRAPH DB (SQLite) ─────────
const database_1 = require("../../06-memory/database/database");
function ensureCloudGraphTable() {
    const db = (0, database_1.getDb)();
    db.exec(`CREATE TABLE IF NOT EXISTS graph_entities (id INTEGER PRIMARY KEY AUTOINCREMENT, entity_name TEXT NOT NULL, entity_type TEXT NOT NULL, pattern_id TEXT)`);
    db.exec(`CREATE TABLE IF NOT EXISTS graph_relationships (id INTEGER PRIMARY KEY AUTOINCREMENT, from_pattern TEXT NOT NULL, to_pattern TEXT NOT NULL, rel_type TEXT NOT NULL, strength REAL NOT NULL DEFAULT 1.0, evidence TEXT)`);
}
function recordCloudEntity(entity_name, entity_type, pattern_id) {
    const db = (0, database_1.getDb)();
    db.prepare(`INSERT INTO graph_entities (entity_name, entity_type, pattern_id) VALUES (?, ?, ?)`).run(entity_name, entity_type, pattern_id);
}
function getCloudEntities() {
    const db = (0, database_1.getDb)();
    const rows = db.prepare(`SELECT entity_name, entity_type, COUNT(*) as patternCount FROM graph_entities GROUP BY entity_name, entity_type`).all();
    return rows.map(r => ({ name: r.entity_name, type: r.entity_type, patternCount: r.patternCount }));
}
function recordCloudRelationship(from, to, type, strength, evidence) {
    const db = (0, database_1.getDb)();
    db.prepare(`INSERT INTO graph_relationships (from_pattern, to_pattern, rel_type, strength, evidence) VALUES (?, ?, ?, ?, ?)`).run(from, to, type, strength, evidence);
}
function getCloudRelationships() {
    const db = (0, database_1.getDb)();
    const rows = db.prepare(`SELECT from_pattern, to_pattern, rel_type, strength FROM graph_relationships`).all();
    return rows.map(r => ({ from: r.from_pattern, to: r.to_pattern, type: r.rel_type, strength: r.strength }));
}
function getCloudPathTraversal(from, to, maxDepth = 10) {
    const db = (0, database_1.getDb)();
    const rows = db.prepare(`SELECT from_pattern, to_pattern, rel_type, strength FROM graph_relationships`).all();
    const adj = new Map();
    for (const r of rows) {
        if (!adj.has(r.from_pattern))
            adj.set(r.from_pattern, []);
        adj.get(r.from_pattern).push({ to: r.to_pattern, type: r.rel_type, weight: r.strength });
        if (!adj.has(r.to_pattern))
            adj.set(r.to_pattern, []);
        adj.get(r.to_pattern).push({ to: r.from_pattern, type: r.rel_type, weight: r.strength });
    }
    const results = [];
    function bfs(start, target) {
        const queue = [{ node: start, path: [start], edgeTypes: [], weight: 0 }];
        const visited = new Set();
        while (queue.length > 0) {
            const cur = queue.shift();
            if (cur.node === target && cur.path.length > 1) {
                results.push({ nodes: cur.path, edges: cur.edgeTypes, totalWeight: cur.weight });
                continue;
            }
            if (cur.path.length > maxDepth)
                continue;
            const neighbors = adj.get(cur.node) || [];
            for (const nb of neighbors) {
                if (!visited.has(nb.to) || nb.to === target) {
                    visited.add(nb.to);
                    queue.push({ node: nb.to, path: [...cur.path, nb.to], edgeTypes: [...cur.edgeTypes, nb.type], weight: cur.weight + nb.weight });
                }
            }
        }
    }
    bfs(from, to);
    return results.sort((a, b) => b.totalWeight - a.totalWeight);
}
function getCloudNodeNeighbors(nodeId) {
    const db = (0, database_1.getDb)();
    const rows = db.prepare(`SELECT from_pattern, to_pattern, rel_type, strength FROM graph_relationships WHERE from_pattern = ? OR to_pattern = ?`).all(nodeId, nodeId);
    const neighbors = new Map();
    for (const r of rows) {
        const neighborId = r.from_pattern === nodeId ? r.to_pattern : r.from_pattern;
        const key = neighborId + '|' + r.rel_type;
        if (!neighbors.has(key) || neighbors.get(key).weight < r.strength)
            neighbors.set(key, { neighborId, edgeType: r.rel_type, weight: r.strength });
    }
    return Array.from(neighbors.values());
}
//# sourceMappingURL=knowledge-graph.js.map