import { chmodSync } from "node:fs";
import { mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";
import { dirname } from "node:path";
import { randomUUID } from "node:crypto";
import { config } from "../config.js";
const EMPTY = { projects: {} };
async function ensureDir() {
    await mkdir(dirname(config.mcpStdioTrustFile), { recursive: true });
}
async function atomicWrite(data) {
    await ensureDir();
    const path = config.mcpStdioTrustFile;
    const tmp = `${path}.${randomUUID()}.tmp`;
    await writeFile(tmp, JSON.stringify(data, null, 2), { mode: 0o600 });
    try {
        chmodSync(tmp, 0o600);
    }
    catch {
        // best-effort
    }
    try {
        await rename(tmp, path);
    }
    catch (err) {
        await unlink(tmp).catch(() => undefined);
        throw err;
    }
}
async function readAll() {
    try {
        const raw = await readFile(config.mcpStdioTrustFile, "utf8");
        if (raw.trim().length === 0)
            return { projects: {} };
        const parsed = JSON.parse(raw);
        if (typeof parsed !== "object" || parsed === null || !("projects" in parsed)) {
            return { projects: {} };
        }
        const projects = parsed.projects;
        if (typeof projects !== "object" || projects === null)
            return { projects: {} };
        const out = { projects: {} };
        for (const [pid, val] of Object.entries(projects)) {
            if (typeof val !== "object" || val === null)
                continue;
            const trustedAt = val.trustedAt;
            if (typeof trustedAt !== "string")
                continue;
            out.projects[pid] = { trustedAt };
        }
        return out;
    }
    catch (err) {
        if (err.code === "ENOENT")
            return { projects: {} };
        throw err;
    }
}
export async function isStdioTrustedForProject(projectId) {
    const cur = await readAll();
    return cur.projects[projectId] !== undefined;
}
export async function grantStdioTrust(projectId) {
    const cur = await readAll();
    if (cur.projects[projectId] !== undefined)
        return;
    cur.projects[projectId] = { trustedAt: new Date().toISOString() };
    await atomicWrite(cur);
}
export async function revokeStdioTrust(projectId) {
    const cur = await readAll();
    if (cur.projects[projectId] === undefined)
        return;
    delete cur.projects[projectId];
    await atomicWrite(cur);
}
/**
 * Drop the trust record on project delete so the file doesn't
 * accumulate orphans. Mirrors the skill/tool/prompt-overrides
 * cleanup hook called from project-manager.deleteProject.
 */
export async function clearProjectStdioTrust(projectId) {
    await revokeStdioTrust(projectId);
}
/** Exported for tests so the empty-state branch is reachable. */
export const _EMPTY_FOR_TESTS = EMPTY;
//# sourceMappingURL=stdio-trust.js.map