"use strict";
// Run transcripts — structured capture of agent execution output.
//
// Records tool calls, token usage, duration, and status for each sub-agent
// run. Persisted as `.harness/transcripts/<id>.json` and events are
// emitted for live UI updates.
//
// Mirrors the Paperclip "transcripts" concept but uses our JSON-file
// persistence pattern and event system.
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.listTranscripts = listTranscripts;
exports.getTranscript = getTranscript;
exports.createTranscript = createTranscript;
exports.updateTranscript = updateTranscript;
exports.appendToolCall = appendToolCall;
exports.addTokenUsage = addTokenUsage;
exports.completeTranscript = completeTranscript;
exports.pruneOldTranscripts = pruneOldTranscripts;
const crypto = __importStar(require("crypto"));
const fs = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
const eventStore_1 = require("../persistence/eventStore");
// ─── Paths ──────────────────────────────────────────────────────────
function transcriptsDir(projectDir) {
    return path.join(projectDir, '.harness', 'transcripts');
}
function transcriptFile(projectDir, id) {
    return path.join(transcriptsDir(projectDir), `${id}.json`);
}
// ─── CRUD ───────────────────────────────────────────────────────────
async function listTranscripts(projectDir, filter) {
    const dir = transcriptsDir(projectDir);
    let entries;
    try {
        entries = await fs.readdir(dir, { withFileTypes: true });
    }
    catch {
        return [];
    }
    const transcripts = [];
    for (const entry of entries) {
        if (!entry.isFile() || !entry.name.endsWith('.json'))
            continue;
        try {
            const raw = await fs.readFile(path.join(dir, entry.name), 'utf-8');
            const t = JSON.parse(raw);
            if (filter?.taskId && t.taskId !== filter.taskId)
                continue;
            if (filter?.agentId && t.agentId !== filter.agentId)
                continue;
            if (filter?.companyId && t.companyId !== filter.companyId)
                continue;
            if (filter?.status && t.status !== filter.status)
                continue;
            transcripts.push(t);
        }
        catch {
            // Skip corrupt files
        }
    }
    return transcripts.sort((a, b) => b.startedAt.localeCompare(a.startedAt));
}
async function getTranscript(projectDir, id) {
    try {
        const raw = await fs.readFile(transcriptFile(projectDir, id), 'utf-8');
        return JSON.parse(raw);
    }
    catch {
        return undefined;
    }
}
async function createTranscript(projectDir, input, now = new Date()) {
    const id = crypto.randomUUID();
    const transcript = {
        id,
        taskId: input.taskId,
        agentId: input.agentId,
        model: input.model,
        companyId: input.companyId,
        startedAt: now.toISOString(),
        status: 'running',
        toolCalls: [],
        tokenUsage: { input: 0, output: 0 },
        outputSummary: '',
    };
    await fs.mkdir(transcriptsDir(projectDir), { recursive: true });
    await fs.writeFile(transcriptFile(projectDir, id), JSON.stringify(transcript, null, 2), 'utf-8');
    await (0, eventStore_1.emitEvent)(projectDir, 'service', 'transcript.created', { transcript }, 'system', id).catch(() => { });
    return transcript;
}
async function updateTranscript(projectDir, id, input, now = new Date()) {
    const existing = await getTranscript(projectDir, id);
    if (!existing)
        throw new Error(`Transcript not found: ${id}`);
    const updated = {
        ...existing,
        ...(input.completedAt !== undefined ? { completedAt: input.completedAt } : {}),
        ...(input.status !== undefined ? { status: input.status } : {}),
        ...(input.toolCalls !== undefined ? { toolCalls: input.toolCalls } : {}),
        ...(input.tokenUsage !== undefined ? { tokenUsage: input.tokenUsage } : {}),
        ...(input.outputSummary !== undefined ? { outputSummary: input.outputSummary } : {}),
        ...(input.fullOutput !== undefined ? { fullOutput: input.fullOutput } : {}),
        ...(input.error !== undefined ? { error: input.error } : {}),
    };
    await fs.mkdir(transcriptsDir(projectDir), { recursive: true });
    await fs.writeFile(transcriptFile(projectDir, id), JSON.stringify(updated, null, 2), 'utf-8');
    const eventType = updated.status === 'completed' ? 'transcript.completed'
        : updated.status === 'failed' ? 'transcript.failed'
            : 'transcript.updated';
    await (0, eventStore_1.emitEvent)(projectDir, 'service', eventType, { transcript: updated }, 'system', id).catch(() => { });
    return updated;
}
/**
 * Append a tool call record to a running transcript.
 */
async function appendToolCall(projectDir, id, toolCall) {
    const existing = await getTranscript(projectDir, id);
    if (!existing)
        throw new Error(`Transcript not found: ${id}`);
    existing.toolCalls.push(toolCall);
    await fs.writeFile(transcriptFile(projectDir, id), JSON.stringify(existing, null, 2), 'utf-8');
    return existing;
}
/**
 * Add token usage to a transcript (incrementally).
 */
async function addTokenUsage(projectDir, id, usage) {
    const existing = await getTranscript(projectDir, id);
    if (!existing)
        throw new Error(`Transcript not found: ${id}`);
    existing.tokenUsage = {
        input: existing.tokenUsage.input + (usage.input ?? 0),
        output: existing.tokenUsage.output + (usage.output ?? 0),
    };
    await fs.writeFile(transcriptFile(projectDir, id), JSON.stringify(existing, null, 2), 'utf-8');
    return existing;
}
/**
 * Complete a transcript — set status, summary, and completedAt.
 */
async function completeTranscript(projectDir, id, result, now = new Date()) {
    return updateTranscript(projectDir, id, {
        status: result.success ? 'completed' : 'failed',
        completedAt: now.toISOString(),
        outputSummary: result.summary,
        fullOutput: result.fullOutput,
        error: result.error,
    }, now);
}
/**
 * Delete old transcripts older than a given number of days.
 */
async function pruneOldTranscripts(projectDir, maxAgeDays = 30, now = new Date()) {
    const dir = transcriptsDir(projectDir);
    let entries;
    try {
        entries = await fs.readdir(dir, { withFileTypes: true });
    }
    catch {
        return 0;
    }
    const cutoff = new Date(now.getTime() - maxAgeDays * 24 * 60 * 60 * 1000);
    let removed = 0;
    for (const entry of entries) {
        if (!entry.isFile() || !entry.name.endsWith('.json'))
            continue;
        try {
            const raw = await fs.readFile(path.join(dir, entry.name), 'utf-8');
            const t = JSON.parse(raw);
            if (t.startedAt && new Date(t.startedAt) < cutoff) {
                await fs.unlink(path.join(dir, entry.name));
                removed++;
            }
        }
        catch {
            // Skip corrupt files
        }
    }
    return removed;
}
//# sourceMappingURL=runTranscripts.js.map