Files
Genarrative/apps/ai-game-creator-shell/scripts/process-session-real-e2e-fixture.mjs
T
AIGameCreator App 580e4dd87f 修正持久进程真实验收协议
将 process-session fixture 改为不依赖控制面和 namespace 身份的纯 PTY 协议
使用 durable start、readiness、cursor、stdin 哈希和 cwd 进程归零校验交互链
新增真实 Node 子进程 smoke 覆盖 readiness、精确回显与停止状态
记录 Provider 瞬态失败和可信 exec-ready 两阶段协议
同步长期决策、技术方案与沙箱验收踩坑
2026-07-14 06:35:43 +08:00

56 lines
1.5 KiB
JavaScript

export function buildProcessSessionFixtureSource({
readyPrefix,
echoPrefix,
stoppedMarker,
}) {
for (const [name, value] of Object.entries({
readyPrefix,
echoPrefix,
stoppedMarker,
})) {
if (
typeof value !== 'string' ||
value.length === 0 ||
/[\r\n]/u.test(value)
) {
throw new Error(`invalid process fixture marker: ${name}`);
}
}
return [
"import { randomBytes } from 'node:crypto';",
'',
`const readyPrefix = ${JSON.stringify(readyPrefix)};`,
`const echoPrefix = ${JSON.stringify(echoPrefix)};`,
`const stoppedMarker = ${JSON.stringify(stoppedMarker)};`,
"const challenge = randomBytes(18).toString('hex');",
'let echoed = false;',
'let stopping = false;',
'',
'function stop() {',
' if (stopping) return;',
' stopping = true;',
' console.log(stoppedMarker);',
' process.exit(0);',
'}',
"for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) process.on(signal, stop);",
"console.log(readyPrefix + ' challenge=' + challenge);",
'',
"process.stdin.setEncoding('utf8');",
"let buffered = '';",
"process.stdin.on('data', (chunk) => {",
' buffered += chunk;',
' const lines = buffered.split(/\\r?\\n/u);',
" buffered = lines.pop() ?? '';",
' for (const line of lines) {',
' if (!echoed && line === challenge) {',
' echoed = true;',
" console.log(echoPrefix + ' ' + challenge);",
' }',
' }',
'});',
'process.stdin.resume();',
'',
].join('\n');
}