import { cp, mkdir, readFile, rm, writeFile } from 'node:fs/promises'; import { createHash } from 'node:crypto'; import { resolve } from 'node:path'; const projectRoot = resolve(import.meta.dirname, '..'); const nextRoot = resolve(projectRoot, '.next'); const outputRoot = resolve(process.argv[2] || resolve(projectRoot, 'dist/makelore-player')); const sourceHtml = resolve(nextRoot, 'server/app/makelore-player.html'); const sourceStatic = resolve(nextRoot, 'static'); const sourceAvatars = resolve(projectRoot, 'public/avatars'); const sourcePublic = resolve(projectRoot, 'public'); const html = await readFile(sourceHtml, 'utf8').catch(() => { throw new Error('Missing .next player output. Run `pnpm build` first.'); }); await rm(outputRoot, { recursive: true, force: true }); await mkdir(resolve(outputRoot, '_next'), { recursive: true }); await writeFile(resolve(outputRoot, 'index.html'), html, 'utf8'); await cp(sourceStatic, resolve(outputRoot, '_next/static'), { recursive: true }); await cp(sourceAvatars, resolve(outputRoot, 'avatars'), { recursive: true }); // Makelore serves this tree through a strict local allowlist. Production Stage // and PBL chunks still contain root-relative public references, so omitting the // producer-owned assets creates a player that builds successfully but 404s at // runtime. await cp(sourcePublic, resolve(outputRoot, 'public'), { recursive: true }); await writeFile(resolve(outputRoot, 'artifact.json'), JSON.stringify({ schemaVersion: 1, entrypoint: 'index.html', source: 'OpenMAIC production Stage', publicDirectory: 'public', publicAssets: [ 'mailuo-logo.png', 'openmaic-mark.png', 'logo-horizontal.png', 'avatars/', 'logos/', 'vendor/', ], htmlSha256: createHash('sha256').update(html).digest('hex'), }, null, 2)); process.stdout.write(`Makelore player artifact: ${outputRoot}\n`);