// engine/marketplace-fetcher/cache.ts — SPEC-681: Raw content cache for fetched skills
// Reads/writes to .planu/skill-cache/{source}/{skillName}.md (NOT planu/ — internal cache).
import { mkdir, readFile, writeFile } from 'node:fs/promises';
import { dirname, join } from 'node:path';
// ---------------------------------------------------------------------------
// Constants — single exported location (no per-call literals)
// ---------------------------------------------------------------------------
export const DEFAULT_CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
export const FETCHED_HEADER_PREFIX = '<!-- fetched:';
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function cachePath(projectPath, source, skillName) {
    return join(projectPath, '.planu', 'skill-cache', source, `${skillName}.md`);
}
/** Parse the fetchedAt ISO timestamp from the header comment in a cached file. */
function parseFetchedAt(content) {
    const match = /^<!-- fetched: ([^>]+) -->/.exec(content);
    return match?.[1]?.trim() ?? null;
}
/** Strip the header comment and return the raw skill content. */
function stripHeader(content) {
    return content.replace(/^<!-- fetched: [^>]+ -->\n/, '');
}
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/**
 * Read from .planu/skill-cache/{source}/{skillName}.md.
 * Returns null if the file is missing or older than maxAgeMs.
 */
export async function readCache(projectPath, source, skillName, maxAgeMs = DEFAULT_CACHE_TTL_MS) {
    const filePath = cachePath(projectPath, source, skillName);
    let raw;
    try {
        raw = await readFile(filePath, 'utf-8');
    }
    catch {
        return null;
    }
    const fetchedAt = parseFetchedAt(raw);
    if (!fetchedAt) {
        return null;
    }
    const ageMs = Date.now() - new Date(fetchedAt).getTime();
    if (ageMs > maxAgeMs) {
        return null;
    }
    return {
        content: stripHeader(raw),
        fetchedAt,
    };
}
/**
 * Write raw content to .planu/skill-cache/{source}/{skillName}.md.
 * Prepends a <!-- fetched: ISO_TIMESTAMP --> header comment.
 */
export async function writeCache(projectPath, source, skillName, content) {
    const filePath = cachePath(projectPath, source, skillName);
    await mkdir(dirname(filePath), { recursive: true });
    const timestamp = new Date().toISOString();
    const withHeader = `${FETCHED_HEADER_PREFIX} ${timestamp} -->\n${content}`;
    await writeFile(filePath, withHeader, 'utf-8');
}
//# sourceMappingURL=cache.js.map