zizi 878ad3f7da feat(game-runtime): T1b-α集成段三门全PASS——SIZES九件全≤配额(全栈gz16.5KB),mini-desktop真浏览器证据(probe链/vfx像素哈希×3/CDP真输入),host-dev宿主页+参考件轮1计划
- 门①构建绿:all-plugins barrel+host-dev 双构建日志留档
- 门②SIZES增量实测:九件单件全≤配额,插件gz净增13263B(自律线60K),core基准gz 3222
- 门③浏览器证据:六锚点FNV-1a链verify.ok=true/burst-trail-drift三预设哈希×3重跑一致+几何命中+直方图非空/vignette-dither开关对照哈希互异/CDP dispatchTouchEvent真点击→probe第7条firstInput旁证
- 模板哲学红线被门③实证:particles不内置颜色致首版全黑,host作引擎供色后过——验证门逮住设计而非绕过
- α不接littlejsengine裁定留痕(host.js顶注/index.html/REPORT §4.1),受控面桩即引擎接缝点
- 遗留:probe前四锚tMono=0(冻结lane件,注入时钟拆分留β)
- games/wanglanmei-ref/LOOP-LOG.md:参考件内部预判轮1计划(五要素挂点/插件用法图/mmx资产单13次/红线五条)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 12:39:15 +00:00

59 lines
2.3 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.

/**
* test/harness/static-serve.cjs — host-dev 取证用零依赖静态文件服务器(仅集成段 mini-desktop)
* owner:T1b-α 集成段 | 用法:node static-serve.cjs <root> <port>
*
* 【定位】
* 集成段把 host-dev 构建产物(含 dist/host-bundle.js)serve 在固定端口,供本地 chrome 经
* http://localhost:<port>/ 加载(必须 localhost——宿主 manifest 校验用 crypto.subtle,仅安全上下文可用;
* 走 Tailscale IP 会失安全上下文,见 ui-walkthrough-cdp.md 大原则)。
* 零依赖(node:http/fs/path),由 systemd-run 起为 durable 单元(不随 ssh 会话 teardown 被杀)。
*
* 【安全】仅服务 root 子树内文件;路径含 .. 一律拒绝(防目录穿越)。本服务器仅用于内网取证,不对公网。
*/
'use strict';
const http = require('node:http');
const fs = require('node:fs');
const path = require('node:path');
const ROOT = path.resolve(process.argv[2] || '.');
const PORT = parseInt(process.argv[3] || '4321', 10);
/** 扩展名 → Content-Type(够 host-dev 用即可)。 */
const MIME = {
'.html': 'text/html; charset=utf-8',
'.js': 'text/javascript; charset=utf-8',
'.mjs': 'text/javascript; charset=utf-8',
'.css': 'text/css; charset=utf-8',
'.json': 'application/json; charset=utf-8',
'.png': 'image/png',
'.map': 'application/json; charset=utf-8',
};
const server = http.createServer((req, res) => {
try {
// 去掉 query;'/' → '/index.html'。
let urlPath = decodeURIComponent((req.url || '/').split('?')[0]);
if (urlPath === '/') urlPath = '/index.html';
// 解析到 root 内绝对路径,拒绝穿越。
const abs = path.resolve(ROOT, '.' + urlPath);
if (!abs.startsWith(ROOT)) {
res.writeHead(403); res.end('forbidden'); return;
}
fs.readFile(abs, (err, buf) => {
if (err) { res.writeHead(404); res.end('not found: ' + urlPath); return; }
const ext = path.extname(abs).toLowerCase();
res.writeHead(200, { 'Content-Type': MIME[ext] || 'application/octet-stream' });
res.end(buf);
});
} catch (e) {
res.writeHead(500); res.end('error: ' + (e && e.message || e));
}
});
server.listen(PORT, '0.0.0.0', () => {
// 启动日志(systemd journal 可见,便于探活诊断)。
console.log(`[static-serve] root=${ROOT} port=${PORT} pid=${process.pid}`);
});