import { existsSync, readFileSync } from 'node:fs'; import path from 'node:path'; import process from 'node:process'; const browserRoot = path.resolve(import.meta.dirname, '..'); const shellPath = path.join(browserRoot, 'index.html'); const bootstrapPath = path.join(browserRoot, 'src', 'browser-runtime-bootstrap.js'); const fallbackPath = path.join(browserRoot, 'src', 'browser-spatial-runtime-fallback.js'); const bootStatePath = path.join(browserRoot, 'src', 'runtime', 'boot-state.ts'); const bundledShellSourcePath = path.join(browserRoot, 'src', 'runtime', 'shell.ts'); const failures = []; function assert(condition, message) { if (!condition) { failures.push(message); } } assert(existsSync(shellPath), `Missing authoritative browser shell: ${shellPath}`); assert(existsSync(bootstrapPath), `Missing bootstrap runtime script: ${bootstrapPath}`); assert(existsSync(fallbackPath), `Missing clean-checkout fallback runtime: ${fallbackPath}`); assert(existsSync(bootStatePath), `Missing browser boot-state helper: ${bootStatePath}`); assert(existsSync(bundledShellSourcePath), `Missing bundled runtime shell source: ${bundledShellSourcePath}`); if (existsSync(shellPath)) { const shellHtml = readFileSync(shellPath, 'utf8'); assert( shellHtml.includes('./src/browser-runtime-bootstrap.js'), 'The authoritative browser shell must load the bootstrap runtime script.' ); assert( !shellHtml.includes('browser-spatial-runtime.ts'), 'The authoritative browser shell must not point directly at a TypeScript source entrypoint.' ); } if (existsSync(bundledShellSourcePath)) { const bundledShellSource = readFileSync(bundledShellSourcePath, 'utf8'); assert( bundledShellSource.includes('Browser Runtime Status'), 'The bundled runtime shell must expose the Browser Runtime Status surface.' ); assert( bundledShellSource.includes('queuedCommandCountAtRuntimeReady'), 'The bundled runtime shell must surface retained queued command count at runtime-ready.' ); assert( bundledShellSource.includes('lastShellStateReceivedAtUtc'), 'The bundled runtime shell must surface the latest shell-state receipt timestamp.' ); } if (existsSync(fallbackPath)) { const fallbackSource = readFileSync(fallbackPath, 'utf8'); assert( fallbackSource.includes('Browser Runtime Status'), 'The clean-checkout fallback runtime must expose the Browser Runtime Status surface.' ); assert( fallbackSource.includes('queuedShellStateCountAtRuntimeReady'), 'The fallback runtime must surface retained queued shell-state count at runtime-ready.' ); assert( fallbackSource.includes('lastCommandReceivedAtUtc'), 'The fallback runtime must surface the latest command receipt timestamp.' ); } if (failures.length > 0) { for (const failure of failures) { console.error(failure); } process.exit(1); } console.log('HyperTwist browser shell verification passed.');