import { createHash } from 'node:crypto'; import { readFile, readdir, stat, writeFile } from 'node:fs/promises'; import path from 'node:path'; const root = path.resolve(import.meta.dirname, '..'); const manifestPath = path.join(root, 'PHASE_13_PACKAGE_MANIFEST_v1.0.json'); const excludedDirectories = new Set([ '.git', '.next', 'node_modules', 'coverage', 'playwright-report', 'test-results', ]); const excludedFiles = new Set([ 'PHASE_13_PACKAGE_MANIFEST_v1.0.json', 'package-lock.json', 'tsconfig.tsbuildinfo', ]); async function walk(directory) { const files = []; for (const entry of await readdir(directory, { withFileTypes: true })) { if (entry.isDirectory() && excludedDirectories.has(entry.name)) continue; const fullPath = path.join(directory, entry.name); if (entry.isDirectory()) files.push(...(await walk(fullPath))); else { const relative = path.relative(root, fullPath).split(path.sep).join('/'); if (!excludedFiles.has(relative)) files.push({ fullPath, relative }); } } return files; } const files = (await walk(root)).sort((a, b) => a.relative.localeCompare(b.relative)); const entries = []; for (const file of files) { const contents = await readFile(file.fullPath); const details = await stat(file.fullPath); entries.push({ path: file.relative, bytes: details.size, sha256: createHash('sha256').update(contents).digest('hex'), }); } const manifest = { schema_version: '1.0', project: 'RentalDriveGo', phase: 13, generated_at: '2026-06-25', excludes: [...excludedDirectories, ...excludedFiles], file_count: entries.length, files: entries, }; await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`); console.log(`Generated Phase 13 manifest for ${entries.length} files.`);