import assert from "node:assert/strict"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import test from "node:test"; import { runCleanup } from "./cleanup-copilot-history.mjs"; import { runRestore } from "./restore-copilot-history.mjs"; import { runPurge } from "./purge-copilot-history-quarantine.mjs"; function makeDir(dirPath) { fs.mkdirSync(dirPath, { recursive: true }); return dirPath; } function writeFile(filePath, content = "x") { fs.mkdirSync(path.dirname(filePath), { recursive: true }); fs.writeFileSync(filePath, content, "utf8"); } function readJson(filePath) { return JSON.parse(fs.readFileSync(filePath, "utf8")); } test("cleanup writes a quarantine manifest for exact restore targeting", () => { const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "copilot-history-cleanup-")); const homeDir = path.join(tempRoot, "home"); const repoRoot = path.join(tempRoot, "repo"); const auditDir = makeDir(path.join(repoRoot, ".local", "audits", "forced-run")); writeFile(path.join(auditDir, "selection-manifest.tsv"), "decision\treview_note\n"); writeFile(path.join(auditDir, "promotion-summary.md"), "summary\n"); const oldAuditDir = makeDir(path.join(repoRoot, ".local", "audits", "old-run")); writeFile(path.join(oldAuditDir, "selection-manifest.tsv"), "decision\treview_note\n"); const workspaceArtifact = makeDir( path.join( homeDir, "Library", "Application Support", "Code", "User", "workspaceStorage", "abc123", "chatSessions", ), ); writeFile(path.join(workspaceArtifact, "session.jsonl"), "{}\n"); const previousHome = process.env.HOME; process.env.HOME = homeDir; try { const result = runCleanup({ repoRoot, auditDir, completionCutoff: "2100-01-01T00:00:00.000Z", scope: "aggressive", quarantineDir: path.join(homeDir, ".copilot-resources-state", "quarantine", "copilot-history-cleanup"), execute: true, }); assert.equal(result.processed, 2); assert.equal(Boolean(result.manifestPath), true); const manifest = readJson(result.manifestPath); assert.equal(manifest.rows.length, 2); assert.deepEqual( manifest.rows.map((row) => row.originalPath).sort(), [ path.join(oldAuditDir), path.join(homeDir, "Library", "Application Support", "Code", "User", "workspaceStorage", "abc123", "chatSessions"), ].sort(), ); } finally { process.env.HOME = previousHome; } }); test("restore exact path limits candidates to one original target", () => { const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "copilot-history-restore-")); const quarantineDir = makeDir(path.join(tempRoot, "quarantine")); const runDir = makeDir(path.join(quarantineDir, "2026-05-24T01-21-04-653Z")); const firstTarget = makeDir(path.join(runDir, "Users", "fragginwagon", "Library", "Application Support", "Code", "User", "workspaceStorage", "aaa", "chatSessions")); const secondTarget = makeDir(path.join(runDir, "Users", "fragginwagon", "Library", "Application Support", "Code", "User", "workspaceStorage", "bbb", "chatEditingSessions")); writeFile(path.join(firstTarget, "session.jsonl"), "{}\n"); writeFile(path.join(secondTarget, "state.json"), "{}\n"); fs.writeFileSync( path.join(runDir, "manifest.json"), JSON.stringify( { createdAt: "2026-05-24T01:21:04.653Z", rows: [ { originalPath: "/Users/fragginwagon/Library/Application Support/Code/User/workspaceStorage/aaa/chatSessions", quarantinePath: firstTarget, }, { originalPath: "/Users/fragginwagon/Library/Application Support/Code/User/workspaceStorage/bbb/chatEditingSessions", quarantinePath: secondTarget, }, ], }, null, 2, ), ); const result = runRestore({ quarantineDir, quarantineRun: runDir, exactPath: "/Users/fragginwagon/Library/Application Support/Code/User/workspaceStorage/aaa/chatSessions", filter: "", overwrite: false, execute: false, }); assert.equal(result.candidates, 1); const summary = fs.readFileSync(result.summaryPath, "utf8"); assert.match(summary, /workspaceStorage\/aaa\/chatSessions/); assert.doesNotMatch(summary, /workspaceStorage\/bbb\/chatEditingSessions/); }); test("purge keeps newest quarantine run and selects older ones before cutoff", () => { const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "copilot-history-purge-")); const quarantineDir = makeDir(path.join(tempRoot, "quarantine")); const oldRun = makeDir(path.join(quarantineDir, "2026-05-20T00-00-00-000Z")); const newRun = makeDir(path.join(quarantineDir, "2026-05-24T00-00-00-000Z")); writeFile(path.join(oldRun, "manifest.json"), "{}\n"); writeFile(path.join(newRun, "manifest.json"), "{}\n"); const oldTime = new Date("2026-05-20T00:00:00.000Z"); const newTime = new Date("2026-05-24T00:00:00.000Z"); fs.utimesSync(oldRun, oldTime, oldTime); fs.utimesSync(newRun, newTime, newTime); const result = runPurge({ quarantineDir, before: "2026-05-23T00:00:00.000Z", keepLatest: 1, execute: false, }); assert.equal(result.considered, 2); assert.equal(result.purged, 0); const summary = fs.readFileSync(result.summaryPath, "utf8"); assert.match(summary, /Protected by keep-latest/); assert.match(summary, /Dry-run: no changes were applied/); });