#!/usr/bin/env node // fs-utils.mjs — Cross-platform file operations for /security clean // Usage: // node fs-utils.mjs backup → prints backup path to stdout // node fs-utils.mjs restore → restores backup over target // node fs-utils.mjs cleanup → removes backup directory // node fs-utils.mjs tmppath → prints cross-platform temp file path import { cpSync, rmSync, renameSync, existsSync } from 'node:fs'; import { join, basename } from 'node:path'; import { tmpdir } from 'node:os'; import { randomUUID } from 'node:crypto'; const [,, command, ...args] = process.argv; switch (command) { case 'backup': { const target = args[0]; if (!target || !existsSync(target)) { console.error(`backup: target does not exist: ${target}`); process.exit(1); } const ts = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19); const backupPath = `${target}.security-backup-${ts}`; cpSync(target, backupPath, { recursive: true }); process.stdout.write(backupPath + '\n'); break; } case 'restore': { const [backup, target] = args; if (!backup || !existsSync(backup)) { console.error(`restore: backup does not exist: ${backup}`); process.exit(1); } if (target && existsSync(target)) { rmSync(target, { recursive: true, force: true }); } renameSync(backup, target); process.stdout.write(`Restored ${backup} → ${target}\n`); break; } case 'cleanup': { const path = args[0]; if (path && existsSync(path)) { rmSync(path, { recursive: true, force: true }); process.stdout.write(`Removed ${path}\n`); } break; } case 'tmppath': { const base = args[0] || 'llm-security-temp.json'; const dotIdx = base.lastIndexOf('.'); const name = dotIdx > 0 ? base.slice(0, dotIdx) : base; const ext = dotIdx > 0 ? base.slice(dotIdx) : '.json'; const unique = `${name}-${randomUUID().slice(0, 8)}${ext}`; process.stdout.write(join(tmpdir(), unique) + '\n'); break; } default: console.error('Usage: node fs-utils.mjs [args...]'); process.exit(1); }