/** * 无人值守 UI 验证:用本地静态服务器托管已构建的渲染产物, * 注入 window.ycode 假桥(真实主进程不可用时的替身),供浏览器读取布局。 * * 用法:node scripts/verify-ui.mjs [port] * 打开 http://127.0.0.1:/ 后用 CDP/浏览器读取 .app-shell 网格列宽。 */ import { createServer } from 'node:http' import { readFile } from 'node:fs/promises' import { extname, join, normalize } from 'node:path' import { fileURLToPath } from 'node:url' import { chatParityFixture } from './fixtures/chat-parity.mjs' import { sourceRecoveryFixture } from './fixtures/source-recovery.mjs' import { dialogueMediaFixture } from './fixtures/dialogue-media.mjs' import { typographyFixture, typographyProbes } from './fixtures/typography.mjs' import { conversationCompleteFixture, conversationCompleteBridge } from './fixtures/conversation-complete.mjs' import { artifactSourceFixture } from './fixtures/artifact-source.mjs' import { pierreDiffFixture } from './fixtures/pierre-diff.mjs' import { conversationStatesFixture, conversationStatesBridge } from './fixtures/conversation-states.mjs' const root = fileURLToPath(new URL('../out/renderer', import.meta.url)) const port = Number(process.argv[2] ?? 8788) const MIME = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8', '.json': 'application/json; charset=utf-8', '.svg': 'image/svg+xml', '.png': 'image/png', '.woff2': 'font/woff2', '.woff': 'font/woff', '.ttf': 'font/ttf' } // 假桥:只提供渲染进程首屏需要的调用,其余返回空/默认值 const STUB = `` const server = createServer(async (req, res) => { try { const urlPath = decodeURIComponent((req.url ?? '/').split('?')[0]) const rel = urlPath === '/' ? '/index.html' : urlPath const filePath = normalize(join(root, rel)) if (!filePath.startsWith(root)) { res.writeHead(403).end('forbidden') return } let body = await readFile(filePath) if (rel.endsWith('.html')) { const fixture = new URL(req.url ?? '/', 'http://127.0.0.1').searchParams.get('fixture') const selectedFixture = fixture === 'conversation-states' ? conversationStatesFixture : fixture === 'pierre-diff' ? pierreDiffFixture : fixture === 'artifact-source' ? artifactSourceFixture : fixture === 'conversation-complete' ? conversationCompleteFixture : fixture === 'chat-parity' ? chatParityFixture : fixture === 'source-recovery' ? sourceRecoveryFixture : fixture === 'dialogue-media' ? dialogueMediaFixture : fixture === 'typography' ? typographyFixture : null const fixtureScript = selectedFixture ? `` : '' // 在首个 module script 之前注入假桥 body = Buffer.from(body.toString('utf8').replace('