import fs from "node:fs";
import path from "node:path";
import crypto from "node:crypto";
export class ExecutionLogger {
    logFile;
    stepCounter = 0;
    constructor(logsDir, taskName) {
        // Filename = date + ms-precision time + random nonce. ms alone isn't
        // enough: two `new Date()` calls in the same tick return the same string.
        // The 32-bit nonce makes collisions within a single millisecond ~1 in 4B,
        // effectively unreachable in practice for concurrent/rapid logger creation
        // (clearChat immediately followed by next chat turn, parallel tasks, etc.).
        const now = new Date().toISOString();
        const date = now.slice(0, 10);
        const time = now.slice(11, 23).replace(/[:.]/g, "-"); // HH-MM-SS-mmm
        const nonce = crypto.randomBytes(4).toString("hex"); // 8 hex chars, 32-bit
        const safeName = taskName.replace(/[^a-zA-Z0-9_-]/g, "_");
        this.logFile = path.join(logsDir, `${date}_${time}_${nonce}_${safeName}.jsonl`);
    }
    log(action, details = {}, success = true) {
        this.stepCounter++;
        const entry = {
            step: this.stepCounter,
            action,
            timestamp: new Date().toISOString(),
            success,
            ...details,
        };
        fs.appendFileSync(this.logFile, JSON.stringify(entry) + "\n", "utf-8");
        return entry;
    }
    getLogFilePath() {
        return this.logFile;
    }
    getStepCount() {
        return this.stepCounter;
    }
    static readLog(logFilePath) {
        const content = fs.readFileSync(logFilePath, "utf-8").trim();
        if (!content)
            return [];
        return content.split("\n").map((line) => JSON.parse(line));
    }
    static listLogs(logsDir) {
        if (!fs.existsSync(logsDir))
            return [];
        return fs
            .readdirSync(logsDir)
            .filter((f) => f.endsWith(".jsonl"))
            .sort()
            .reverse();
    }
}
//# sourceMappingURL=logger.js.map