"use strict";
// context-predictor.ts — Supreme Context Predictor
// Predicts what information AI will need in the NEXT session based on patterns.
// Uses session history, decision patterns, error recurrence, and file focus.
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.predictContext = predictContext;
exports.formatPredictions = formatPredictions;
exports.bridgeWithPredictions = bridgeWithPredictions;
const database_1 = require("../../06-memory/database/database");
const path = __importStar(require("path"));
function getActiveFileSet(project) {
    try {
        const db = (0, database_1.getDb)();
        const rows = db.prepare(`SELECT DISTINCT sf.file_path FROM session_files sf
       JOIN sessions s ON sf.session_id = s.id
       WHERE s.project = ?
       ORDER BY sf.first_touched DESC
       LIMIT 15`).all(project);
        return rows.map((r) => r.file_path);
    }
    catch {
        return [];
    }
}
function getErrorPatterns(project) {
    try {
        const db = (0, database_1.getDb)();
        return db.prepare(`SELECT file_path as file, COUNT(*) as count, MAX(created_at) as lastSeen
       FROM error_log WHERE project = ?
       GROUP BY file_path
       HAVING COUNT(*) >= 2
       ORDER BY count DESC
       LIMIT 5`).all(project);
    }
    catch {
        return [];
    }
}
function getDecisionRevisitLikelihood(project) {
    try {
        const db = (0, database_1.getDb)();
        const decisions = db.prepare(`SELECT technology, reason, was_right FROM decisions
       WHERE project = ?
       ORDER BY created_at DESC
       LIMIT 10`).all(project);
        const predictions = [];
        const undecided = decisions.filter((d) => d.was_right === null);
        const bad = decisions.filter((d) => d.was_right === 0);
        for (const d of undecided.slice(0, 2)) {
            predictions.push({
                type: 'will_ask_about_decision',
                text: `Decision on "${d.technology}" still unresolved — may want to revisit.`,
                confidence: 70,
                reason: d.reason || 'No recorded reason',
                fromSessions: [],
            });
        }
        for (const d of bad.slice(0, 2)) {
            predictions.push({
                type: 'will_refactor',
                text: `Decision on "${d.technology}" was marked WRONG — refactor may be needed.`,
                confidence: 75,
                reason: d.reason || 'No recorded reason',
                fromSessions: [],
            });
        }
        return predictions;
    }
    catch {
        return [];
    }
}
function getTaskContinuation(project) {
    try {
        const db = (0, database_1.getDb)();
        const lastSession = db.prepare('SELECT id, key_decisions, context_snapshot FROM sessions WHERE project = ? ORDER BY id DESC LIMIT 1').get(project);
        if (!lastSession)
            return [];
        let decisions = [];
        try {
            decisions = JSON.parse(lastSession.key_decisions || '[]');
        }
        catch { }
        const predictions = [];
        if (decisions.length > 0) {
            const lastDecisions = decisions.slice(-3);
            for (const d of lastDecisions) {
                if (/started|began|working on|implementing|building|creating/.test(d.toLowerCase())) {
                    predictions.push({
                        type: 'will_continue_task',
                        text: `Task was in progress: "${d}" — likely needs continuation.`,
                        confidence: 80,
                        reason: 'Unfinished task detected in last session decisions',
                        fromSessions: [lastSession.id],
                    });
                }
            }
        }
        return predictions;
    }
    catch {
        return [];
    }
}
function getTimePressure(sessions) {
    if (sessions.length < 3)
        return [];
    const recent = sessions.slice(0, 5);
    let shortCount = 0;
    const allHours = [];
    for (const s of recent) {
        if (s.start_time) {
            const h = new Date(s.start_time).getHours();
            allHours.push(h);
            if (h >= 19 || h <= 2)
                shortCount++;
        }
        if (s.end_time && s.start_time) {
            const dur = new Date(s.end_time).getTime() - new Date(s.start_time).getTime();
            if (dur < 15 * 60 * 1000)
                shortCount++; // <15 min session
        }
    }
    if (shortCount >= 3) {
        return [{
                type: 'time_pressure',
                text: 'Recent sessions have been short/fast — may be working under time pressure.',
                confidence: 70,
                reason: `${shortCount}/${recent.length} recent sessions show time constraints`,
                fromSessions: recent.map((s) => s.id),
            }];
    }
    return [];
}
function getDebuggingMode(project) {
    try {
        const db = (0, database_1.getDb)();
        const recent = db.prepare(`SELECT summary FROM memory_events
       WHERE project = ? AND type IN ('error', 'fix')
       ORDER BY id DESC LIMIT 10`).all(project);
        const errors = recent.filter((e) => e.type === 'error').length;
        const fixes = recent.filter((e) => e.type === 'fix').length;
        if (errors + fixes >= 5 && errors > fixes) {
            return [{
                    type: 'debugging_mode',
                    text: 'In debugging mode — more errors being logged than fixes applied.',
                    confidence: 75,
                    reason: `${errors} errors vs ${fixes} fixes in recent memory`,
                    fromSessions: [],
                }];
        }
        return [];
    }
    catch {
        return [];
    }
}
function generateBeachhead(predictions, project) {
    const highConf = predictions.filter(p => p.confidence >= 70);
    if (highConf.length === 0)
        return null;
    const continueTask = highConf.find(p => p.type === 'will_continue_task');
    const needFile = highConf.find(p => p.type === 'will_need_file');
    const debugging = highConf.find(p => p.type === 'debugging_mode');
    const refactor = highConf.find(p => p.type === 'will_refactor');
    if (continueTask) {
        return {
            text: 'You were in the middle of something.',
            confidence: continueTask.confidence,
            suggestedAction: continueTask.text,
            contextSummary: 'Pick up where the last session left off. Check the last decisions and open questions first.',
        };
    }
    if (refactor) {
        return {
            text: 'A past decision may need rework.',
            confidence: refactor.confidence,
            suggestedAction: refactor.text,
            contextSummary: 'Review recent bad decisions before starting new work.',
        };
    }
    if (debugging) {
        return {
            text: 'You\'re in debugging mode.',
            confidence: debugging.confidence,
            suggestedAction: `Focus on the error patterns: ${predictions.filter(p => p.type === 'will_face_error').map(p => p.text).join('; ')}`,
            contextSummary: 'Debugging mode detected. Address error patterns before new feature work.',
        };
    }
    return {
        text: 'Previous context is available to continue from.',
        confidence: 65,
        suggestedAction: `Review ${predictions.length} context predictions for guidance.`,
        contextSummary: 'Multiple context signals detected from recent sessions.',
    };
}
// Main predictor — runs all analyses and returns state
function predictContext(project, projectDir) {
    const db = (0, database_1.getDb)();
    const sessions = db.prepare('SELECT id, start_time, end_time, tool_name FROM sessions WHERE project = ? ORDER BY id DESC LIMIT 10').all(project);
    let allPredictions = [];
    // 1. Files AI will need
    const activeFiles = getActiveFileSet(project);
    for (const f of activeFiles.slice(0, 5)) {
        allPredictions.push({
            type: 'will_need_file',
            text: `File still in focus: "${path.basename(f)}" — likely needs to open it.`,
            confidence: 65,
            reason: `Frequently touched across sessions`,
            fromSessions: [],
        });
    }
    // 2. Error patterns to watch for
    const errorPatterns = getErrorPatterns(project);
    for (const ep of errorPatterns) {
        allPredictions.push({
            type: 'will_face_error',
            text: `Error in "${path.basename(ep.file)}" has occurred ${ep.count} times — may happen again.`,
            confidence: Math.min(80, ep.count * 15),
            reason: `${ep.count} recurrences, last seen ${ep.lastSeen}`,
            fromSessions: [],
        });
    }
    // 3. Decision revisits
    allPredictions.push(...getDecisionRevisitLikelihood(project));
    // 4. Task continuation
    allPredictions.push(...getTaskContinuation(project));
    // 5. Time pressure
    allPredictions.push(...getTimePressure(sessions));
    // 6. Debugging mode
    allPredictions.push(...getDebuggingMode(project));
    // Sort by confidence
    allPredictions.sort((a, b) => b.confidence - a.confidence);
    const top = allPredictions.slice(0, 10);
    const beachhead = generateBeachhead(top, project);
    // Save state
    try {
        const fs = require('fs');
        const statePath = require('path').join(projectDir, '.cell', 'predictor.json');
        fs.writeFileSync(statePath, JSON.stringify({
            predictions: top,
            beachhead,
            generatedAt: new Date().toISOString(),
            basedOnSessionCount: sessions.length,
        }, null, 2), 'utf-8');
    }
    catch { }
    return {
        predictions: top,
        beachhead,
        generatedAt: new Date().toISOString(),
        basedOnSessionCount: sessions.length,
    };
}
// Format predictions for context block
function formatPredictions(state) {
    const lines = [];
    if (state.predictions.length === 0) {
        lines.push('🔮 PREDICTIONS');
        lines.push('   No predictions yet — more sessions will reveal patterns.');
        return lines.join('\n');
    }
    lines.push('🔮 CONTEXT PREDICTIONS');
    lines.push(`   Based on ${state.basedOnSessionCount} sessions.`);
    if (state.beachhead) {
        lines.push('');
        lines.push(`   🏖️  BEACHHEAD (${state.beachhead.confidence}%):`);
        lines.push(`      ${state.beachhead.text}`);
        lines.push(`      › ${state.beachhead.suggestedAction}`);
    }
    const topPreds = state.predictions.filter(p => p.confidence >= 60).slice(0, 6);
    if (topPreds.length > 0) {
        lines.push('');
        for (const p of topPreds) {
            const icon = p.confidence >= 80 ? '🔴' : p.confidence >= 70 ? '🟡' : '🟢';
            lines.push(`   ${icon} [${p.type}] ${p.text} (${p.confidence}%)`);
        }
    }
    return lines.join('\n');
}
// Inject predictions into the bridge's predictedNextSteps
function bridgeWithPredictions(bridgeNextSteps, state) {
    const merged = [...bridgeNextSteps];
    for (const p of state.predictions.filter(p => p.confidence >= 70)) {
        merged.push(p.text);
    }
    return [...new Set(merged)].slice(0, 8);
}
//# sourceMappingURL=context-predictor.js.map