zizi 11c8eafb42 feat(t1b-beta): A0 引擎掌帧接管落地——host-dev RAF桩→littlejsengine engineInit 五回调;本机门全绿,门0浏览器段待mini-desktop
host.js+entry.js:engineMode 分流。real=引擎掌帧(engineInit 五回调 engGameInit/
Update/UpdatePost/Render/RenderPost 接帧驱动+渲染)+getContext2d backing 切引擎
mainContext(setGLEnable(false) 纯2D渲进 mainContext);stub=α RAF桩原样保留(可回滚点)。

本机已验(主会话亲跑):
- 155单测绿(基线持平,受控面/插件零改故计数不变)
- 受控面零改实证:src/core/api.d.ts+plugin.js 未触(七项 backing 全在 host 层切换)
- Q4边界:引擎 import 仅 host.js+entry.js(metafile importers 反查证),未泄进受控面/插件
- 真接线门①:esbuild metafile 实证 littlejsengine 真入产物(163691 bytesInOutput),
  box2d 惰性(0 wasm input),产物 205KB min

8-agent workflow(源码取证→设计→对抗复审→实现):3/3 concerns 0 fatal。
17 mustFix(P0×1/P1×9/P2×7)全采纳:P0=real像素门 overshoot(引擎追帧 N tick/RAF 墙钟抖动
污染采样帧)→改 stub 通道独占逐像素回归,real 只证掌帧;P1 源码级纠偏=debug水印每帧画
averageFPS入mainContext(setDebugWatermark(false))/clearColor默认alpha=0不铺底
(setCanvasClearColor(BLACK))/P75须读timeReal非mockNowMs(real模式退化逻辑帧钟)。

门0 G0-1~G0-7(引擎真掌帧/真渲2D mainContext/双时钟/无uncaught/水印已除)须 mini-desktop
chrome 实测(6c6g 禁 chrome)——未实测不宣布 A0 完成。

新:docs/agent-specs/2026-06-13-A0-引擎掌帧接管-edit-plan.md(编辑计划+门0 runbook)
   +game-runtime/test/harness/gate0-engine-takeover.cjs(门0 CDP 驱动,独立闭合不复用未改造的 integration-run)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 06:33:27 +00:00

84 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* scripts/build.mjs — LittleJS 增强发行版打包脚本esbuild 锁参core-protocol-v0
*
* ⚠️ 运行环境纪律(执行版 §1/§5
* **本脚本仅在「集成段mini-desktop」运行**,不在 lane 本机跑。lane 阶段一切测试 =
* 零依赖 `node --test`esbuild 是工具链依赖(需 `npm i -D esbuild`),只在 mini-desktop 装与跑。
* 在无 esbuild 的本机执行本脚本会**显式报错并给出安装指引**(不静默失败)。
*
* 锁定参数§5不得擅改 —— 改动影响 SIZES 口径与 channel-spike 对照):
* bundle + minify + format=iife + target=es2019 + sourcemap=false
*
* 用法(集成段):
* node scripts/build.mjs <入口.js> <输出.js> [--global-name=NAME]
* 例node scripts/build.mjs src/core/plugin.js dist/core.iife.js --global-name=GameRuntimeCore
*/
'use strict';
import { argv, exit } from 'node:process';
import { writeFileSync } from 'node:fs';
/** 锁定的 esbuild 构建参数§5 写死,集成段与 size.mjs 必须同口径)。 */
export const LOCKED_BUILD_OPTIONS = {
bundle: true,
minify: true,
format: 'iife',
target: 'es2019',
sourcemap: false,
// legalComments:'none' 去掉许可证注释,保证 minify 后字节口径稳定(不影响合规,许可证在仓内 LICENSE 留存)。
legalComments: 'none',
};
/**
* 用锁定参数构建单个入口。集成段调用;本机无 esbuild 时抛错给指引。
* @param {string} entry 入口文件路径
* @param {string} outfile 输出文件路径
* @param {string} [globalName] iife 全局变量名(可选)
* @returns {Promise<void>}
*/
export async function build(entry, outfile, globalName) {
let esbuild;
try {
// 动态 import仅集成段装了 esbuild 才解析得到;本机解析失败走下方指引。
esbuild = await import('esbuild');
} catch {
console.error(
'[build] 未找到 esbuild —— 本脚本仅在集成段mini-desktop运行。\n' +
' 请在集成段执行npm i -D esbuild再重跑本脚本。\n' +
' lane 本机请勿运行构建(纪律:本机零依赖、只跑 node --test。'
);
throw new Error('esbuild 不可用(非集成段环境)');
}
// 【A0/门1① additive】metafile:true 落 <outfile>.meta.json供 grep 核验「引擎真入包 + 被哪些 chunk 引用」。
// additive不改 LOCKED_BUILD_OPTIONS 锁参口径):移除 metafile 不影响产物字节,仅少一份诊断文件。
const result = await esbuild.build({
...LOCKED_BUILD_OPTIONS,
entryPoints: [entry],
outfile,
metafile: true,
...(globalName ? { globalName } : {}),
});
if (result && result.metafile) {
writeFileSync(outfile + '.meta.json', JSON.stringify(result.metafile));
console.log(`[build] metafile → ${outfile}.meta.json`);
}
console.log(`[build] OK ${entry}${outfile} (iife/es2019/min/no-sourcemap)`);
}
// ── CLI 入口(仅集成段使用)──────────────────────────────────────────────────
// 仅当作为脚本直接运行时执行 CLI被 import如 size.mjs 复用 LOCKED_BUILD_OPTIONS时不触发。
if (import.meta.url === `file://${argv[1]}`) {
const [entry, outfile, ...rest] = argv.slice(2);
if (!entry || !outfile) {
console.error('用法node scripts/build.mjs <入口.js> <输出.js> [--global-name=NAME]');
exit(1);
}
const gn = (rest.find((a) => a.startsWith('--global-name=')) || '').split('=')[1];
build(entry, outfile, gn).catch((e) => {
console.error('[build] 失败:' + (e && e.message ? e.message : e));
exit(1);
});
}