import { cp, mkdir, readFile, rm, writeFile } from 'node:fs/promises'; import { spawn } from 'node:child_process'; import { resolve } from 'node:path'; import { validateLearningPlayerArtifact } from './learning-player-artifact.mjs'; const makeloreRoot = resolve(import.meta.dirname, '..'); const outputRoot = resolve(makeloreRoot, 'build', 'learning-player'); const buildManifest = JSON.parse(await readFile( resolve(import.meta.dirname, 'learning-player-build-manifest.json'), 'utf8', )); function run(command, args, cwd) { return new Promise((resolveRun, rejectRun) => { const child = spawn(command, args, { cwd, stdio: 'inherit', shell: process.platform === 'win32' }); child.once('error', rejectRun); child.once('exit', (code, signal) => { if (code === 0) resolveRun(); else rejectRun(new Error(`${command} ${args.join(' ')} failed (${signal || code})`)); }); }); } async function buildLocalFallback() { if (process.env.CI || process.env.MAKELORE_RELEASE_BUILD === '1') { throw new Error( 'Release builds require MAKELORE_LEARNING_PLAYER_ARTIFACT. Download and verify the versioned OpenMAIC player before packaging.', ); } const learningRoot = resolve( process.env.MAKELORE_LEARNING_SOURCE || resolve(makeloreRoot, buildManifest.localSource.defaultRelativePath), ); const packageJson = JSON.parse(await readFile(resolve(learningRoot, 'package.json'), 'utf8').catch(() => { throw new Error(`OpenMAIC source checkout is unavailable at ${learningRoot}`); })); for (const script of buildManifest.localSource.requiredScripts) { if (typeof packageJson.scripts?.[script] !== 'string') { throw new Error(`OpenMAIC source is missing required script: ${script}`); } } const temporaryOutput = resolve(makeloreRoot, 'build', '.learning-player-local'); await rm(temporaryOutput, { recursive: true, force: true }); await run('pnpm', ['run', 'build'], learningRoot); await run('pnpm', ['run', 'build:makelore-player', '--', temporaryOutput], learningRoot); return temporaryOutput; } const explicitArtifact = process.env.MAKELORE_LEARNING_PLAYER_ARTIFACT?.trim(); const sourceRoot = explicitArtifact ? resolve(explicitArtifact) : await buildLocalFallback(); if (sourceRoot === outputRoot) { throw new Error('MAKELORE_LEARNING_PLAYER_ARTIFACT must not point at build/learning-player'); } const verified = await validateLearningPlayerArtifact(sourceRoot); await rm(outputRoot, { recursive: true, force: true }); await mkdir(resolve(outputRoot, '..'), { recursive: true }); await cp(verified.root, outputRoot, { recursive: true }); await writeFile(resolve(outputRoot, 'makelore-build.json'), JSON.stringify({ schemaVersion: 1, sourceKind: explicitArtifact ? 'versioned-artifact' : 'local-source-build', htmlSha256: verified.htmlSha256, }, null, 2)); await validateLearningPlayerArtifact(outputRoot); process.stdout.write(`Synced verified OpenMAIC player to ${outputRoot}\n`);