import { lstatSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs'; import { basename, join, relative, resolve, sep } from 'node:path'; import { randomUUID } from 'node:crypto'; export const OWNERSHIP_FILE = '.maestro-e2e-owned'; export function createOwnedRunDir(cacheRoot, prefix) { mkdirSync(cacheRoot, { recursive: true }); const directory = mkdtempSync(join(realpathSync(cacheRoot), prefix)); const token = randomUUID(); writeFileSync(join(directory, OWNERSHIP_FILE), token, { mode: 0o600 }); return { directory, token }; } export function cleanupOwnedRunDir({ cacheRoot, directory, prefix, token }) { if (!directory || !token || !prefix) return false; let rootReal; let directoryReal; try { rootReal = realpathSync(cacheRoot); if (lstatSync(directory).isSymbolicLink()) return false; directoryReal = realpathSync(directory); } catch (error) { if (error?.code === 'ENOENT') return false; throw error; } const rel = relative(rootReal, directoryReal); if (!rel || rel === '..' || rel.startsWith(`..${sep}`) || resolve(rootReal, rel) !== directoryReal) return false; if (!basename(directoryReal).startsWith(prefix)) return false; let actualToken; try { actualToken = readFileSync(join(directoryReal, OWNERSHIP_FILE), 'utf8'); } catch { return false; } if (actualToken !== token) return false; rmSync(directoryReal, { recursive: true, force: true }); return true; }