"use strict";
// context-bridge.ts — Supreme Session Bridge
// Rich session-end capture. Auto-injects at next session start.
// The bridge ensures AI never starts a session "blind" — always has previous context.
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.captureSessionBridge = captureSessionBridge;
exports.consumeSessionBridge = consumeSessionBridge;
exports.peekSessionBridge = peekSessionBridge;
exports.isBridgeStale = isBridgeStale;
exports.autoGenerateBridge = autoGenerateBridge;
exports.formatBridgeForContext = formatBridgeForContext;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const database_1 = require("../../06-memory/database/database");
function getBridgeDir(projectDir) {
    const d = path.join(projectDir, '.cell', 'bridge');
    if (!fs.existsSync(d))
        fs.mkdirSync(d, { recursive: true });
    return d;
}
function bridgeFilePath(projectDir) {
    return path.join(getBridgeDir(projectDir), 'latest.json');
}
// CAPTURE: Called at session end — full snapshot of everything AI needs to remember
function captureSessionBridge(projectDir, params) {
    const bridge = {
        fromSessionId: params.sessionId,
        capturedAt: new Date().toISOString(),
        consumed: false,
        project: params.project,
        tool: params.tool,
        summary: params.summary,
        status: params.status,
        filesTouched: params.filesTouched,
        keyDecisions: params.keyDecisions,
        openQuestions: params.openQuestions,
        failedApproaches: params.failedApproaches,
        workingApproaches: params.workingApproaches,
        lastThought: params.lastThought,
        vibeAtCapture: '',
        predictedNextSteps: params.predictedNextSteps,
    };
    // Try to read vibes
    try {
        const vibePath = path.join(projectDir, '.cell', 'vibe', 'vibe-summary.json');
        if (fs.existsSync(vibePath)) {
            const v = JSON.parse(fs.readFileSync(vibePath, 'utf-8'));
            bridge.vibeAtCapture = v.summary || '';
        }
    }
    catch { }
    const dir = getBridgeDir(projectDir);
    fs.writeFileSync(bridgeFilePath(projectDir), JSON.stringify(bridge, null, 2), 'utf-8');
    // Also archive old bridges
    const archiveFile = path.join(dir, `bridge-${params.sessionId}-${Date.now()}.json`);
    fs.writeFileSync(archiveFile, JSON.stringify(bridge, null, 2), 'utf-8');
    // Cleanup old archives — keep last 10
    const archives = fs.readdirSync(dir)
        .filter(f => f.startsWith('bridge-') && f.endsWith('.json'))
        .sort()
        .reverse();
    for (const f of archives.slice(10)) {
        fs.unlinkSync(path.join(dir, f));
    }
    return bridge;
}
// CONSUME: Called at session start — auto-inject previous bridge
function consumeSessionBridge(projectDir, currentSessionId) {
    const bp = bridgeFilePath(projectDir);
    if (!fs.existsSync(bp))
        return null;
    const bridge = JSON.parse(fs.readFileSync(bp, 'utf-8'));
    if (bridge.consumed)
        return null; // Already used
    bridge.consumed = true;
    bridge.consumedAt = new Date().toISOString();
    bridge.toSessionId = currentSessionId;
    fs.writeFileSync(bp, JSON.stringify(bridge, null, 2), 'utf-8');
    return bridge;
}
// Get bridge without consuming (for display)
function peekSessionBridge(projectDir) {
    const bp = bridgeFilePath(projectDir);
    if (!fs.existsSync(bp))
        return null;
    return JSON.parse(fs.readFileSync(bp, 'utf-8'));
}
// Check staleness — warn if bridge is older than 24 hours
function isBridgeStale(projectDir) {
    const bridge = peekSessionBridge(projectDir);
    if (!bridge)
        return false;
    const age = Date.now() - new Date(bridge.capturedAt).getTime();
    return age > 24 * 60 * 60 * 1000; // 24 hours
}
// Auto-generate bridge if one doesn't exist (from DB)
function autoGenerateBridge(projectDir, project) {
    try {
        const db = (0, database_1.getDb)();
        const lastSession = db.prepare('SELECT id, tool_name, start_time, end_time, files_touched, key_decisions, context_snapshot FROM sessions WHERE project = ? ORDER BY id DESC LIMIT 1').get(project);
        if (!lastSession)
            return null;
        const approaches = db.prepare('SELECT approach, status, reason FROM session_approaches WHERE session_id = ? ORDER BY id DESC LIMIT 20').all(lastSession.id);
        const questions = db.prepare('SELECT question, resolved FROM session_questions WHERE session_id = ? ORDER BY id DESC LIMIT 10').all(lastSession.id);
        const failed = approaches.filter((a) => a.status === 'failed' || a.status === 'rejected').map((a) => a.approach);
        const worked = approaches.filter((a) => a.status === 'accepted' || a.status === 'worked').map((a) => a.approach);
        let files = [];
        try {
            files = JSON.parse(lastSession.files_touched || '[]');
        }
        catch { }
        let decisions = [];
        try {
            decisions = JSON.parse(lastSession.key_decisions || '[]');
        }
        catch { }
        return captureSessionBridge(projectDir, {
            sessionId: lastSession.id,
            project,
            tool: lastSession.tool_name || 'unknown',
            summary: lastSession.context_snapshot || 'No summary captured.',
            status: 'completed',
            filesTouched: files,
            keyDecisions: decisions,
            openQuestions: questions.filter((q) => !q.resolved).map((q) => q.question),
            failedApproaches: failed,
            workingApproaches: worked,
            lastThought: decisions.slice(-3).join('; ') || 'No explicit closing thought captured.',
            predictedNextSteps: [],
        });
    }
    catch {
        return null;
    }
}
// Format the bridge for injection into AI context
function formatBridgeForContext(bridge) {
    const lines = [];
    lines.push('🌉 LAST SESSION BRIDGE');
    lines.push(`   Completed: ${bridge.capturedAt.split('T')[0]} via ${bridge.tool}`);
    lines.push(`   Status: ${bridge.status}`);
    if (bridge.summary && bridge.summary !== 'No summary captured.') {
        lines.push('');
        lines.push(`   📝 SUMMARY: ${bridge.summary}`);
    }
    if (bridge.keyDecisions.length > 0) {
        lines.push('');
        lines.push('   🎯 KEY DECISIONS:');
        for (const d of bridge.keyDecisions.slice(-5)) {
            lines.push(`     • ${d}`);
        }
    }
    if (bridge.keyDecisions.length > 0) {
        lines.push('');
        lines.push(`   💭 LAST THOUGHT: ${bridge.lastThought}`);
    }
    if (bridge.openQuestions.length > 0) {
        lines.push('');
        lines.push('   ❓ UNRESOLVED:');
        for (const q of bridge.openQuestions.slice(0, 5)) {
            lines.push(`     ? ${q}`);
        }
    }
    if (bridge.failedApproaches.length > 0) {
        lines.push('');
        lines.push('   🚫 DON\'T RETRY:');
        for (const a of bridge.failedApproaches.slice(0, 3)) {
            lines.push(`     ✗ ${a}`);
        }
    }
    if (bridge.workingApproaches.length > 0) {
        lines.push('');
        lines.push('   ✅ APPROACHES THAT WORKED:');
        for (const a of bridge.workingApproaches.slice(0, 3)) {
            lines.push(`     ✓ ${a}`);
        }
    }
    if (bridge.filesTouched.length > 0) {
        lines.push('');
        lines.push('   📁 FILES IN FOCUS:');
        for (const f of bridge.filesTouched.slice(0, 8)) {
            lines.push(`     · ${f}`);
        }
    }
    if (bridge.vibeAtCapture) {
        lines.push('');
        lines.push(`   🎭 VIBE: ${bridge.vibeAtCapture}`);
    }
    return lines.join('\n');
}
//# sourceMappingURL=context-bridge.js.map