Files
makelore/tests/fixtures/fake-pi-rpc-child.mjs

129 lines
3.6 KiB
JavaScript

import { spawn } from 'node:child_process';
let input = '';
let held = null;
let keepAlive = null;
let descendant = null;
const counts = Object.create(null);
function response(command, data = {}) {
return JSON.stringify({
type: 'response',
id: command.id,
command: command.type,
success: true,
data,
});
}
function writeRecord(record) {
process.stdout.write(`${typeof record === 'string' ? record : JSON.stringify(record)}\n`);
}
function handle(command) {
counts[command.type] = (counts[command.type] ?? 0) + 1;
if (command.type === 'echo') {
writeRecord(response(command, { value: command.value }));
return;
}
if (command.type === 'emit_event') {
writeRecord({ type: 'agent_start', marker: command.marker });
writeRecord(response(command, { emitted: true }));
return;
}
if (command.type === 'hold') {
held = command;
return;
}
if (command.type === 'release') {
writeRecord(response(command, { order: 'first' }));
if (held) {
writeRecord(response(held, { order: 'second' }));
held = null;
}
return;
}
if (command.type === 'partial') {
const record = `${response(command, { partial: true })}\n`;
process.stdout.write(record.slice(0, 7));
setTimeout(() => process.stdout.write(record.slice(7, 19)), 5);
setTimeout(() => process.stdout.write(record.slice(19)), 10);
return;
}
if (command.type === 'malformed') {
process.stdout.write('not-json\n');
return;
}
if (command.type === 'blank') {
process.stdout.write('\n');
return;
}
if (command.type === 'invalid_utf8') {
process.stdout.write(Buffer.from([0xff, 0x0a]));
return;
}
if (command.type === 'trailing_partial') {
process.stdout.write(response(command, { partial: true }));
setTimeout(() => process.exit(0), 5);
return;
}
if (command.type === 'large') {
writeRecord(response(command, { value: 'x'.repeat(command.bytes ?? 4096) }));
return;
}
if (command.type === 'get_state' && command.fakeRetry) {
if (counts.get_state > 1) writeRecord(response(command, { attempts: counts.get_state }));
return;
}
if (command.type === 'no_response' || command.type === 'prompt') return;
if (command.type === 'stats') {
writeRecord(response(command, { counts }));
return;
}
if (command.type === 'stderr_secret') {
const secret = process.env.FAKE_PI_SECRET ?? 'missing-secret';
process.stderr.write(`${'diagnostic '.repeat(50)}\n`);
process.stderr.write(`Authorization: Bearer ${secret}\n`);
process.stderr.write(`token=${secret}\n`);
writeRecord(response(command, { wrote: true }));
return;
}
if (command.type === 'spawn_descendant') {
descendant = spawn(process.execPath, ['-e', 'setInterval(() => {}, 1000)'], {
stdio: 'ignore',
windowsHide: true,
});
keepAlive = setInterval(() => {}, 1000);
writeRecord(response(command, { pid: descendant.pid }));
return;
}
if (command.type === 'crash') {
process.exit(7);
}
writeRecord({
type: 'response',
id: command.id,
command: command.type,
success: false,
error: 'unsupported fake command',
});
}
process.stdin.setEncoding('utf8');
process.stdin.on('data', (chunk) => {
input += chunk;
while (true) {
const newline = input.indexOf('\n');
if (newline === -1) break;
const line = input.slice(0, newline).replace(/\r$/, '');
input = input.slice(newline + 1);
if (line) handle(JSON.parse(line));
}
});
process.stdin.on('end', () => {
if (!keepAlive) process.exit(0);
});
process.on('exit', () => {
if (keepAlive) clearInterval(keepAlive);
});