Pinned pi SDK 0.85.1 bridge, Python supervisor, artifact exporter, scripted backend peer, image checks and boundary checks under agent/**. Review findings F1-F3 are recorded in docs/implementation/PI_AGENT_REVIEW.md.
23 lines
1.1 KiB
TypeScript
23 lines
1.1 KiB
TypeScript
import net from 'node:net';
|
|
import { createInterface } from 'node:readline';
|
|
export function supervisorChannel(): { deadline: (ms: number) => void; reap: () => Promise<void> } | undefined {
|
|
const fd = process.env.AGENT_SUPERVISOR_FD;
|
|
if (!fd || !/^\d+$/.test(fd)) return undefined;
|
|
const socket = new net.Socket({ fd: Number(fd), readable: true, writable: true });
|
|
const lines = createInterface({ input: socket });
|
|
let awaiting: { resolve: () => void; reject: (err: Error) => void } | undefined;
|
|
lines.on('line', line => {
|
|
if (line !== '{"type":"reaped"}' || !awaiting) { socket.destroy(); return; }
|
|
awaiting.resolve(); awaiting = undefined;
|
|
});
|
|
socket.on('error', () => { awaiting?.reject(new Error('Supervisor unavailable')); awaiting = undefined; });
|
|
socket.on('close', () => { awaiting?.reject(new Error('Supervisor unavailable')); awaiting = undefined; });
|
|
return {
|
|
deadline: ms => { socket.write(JSON.stringify({ type: 'set_deadline', remaining_ms: ms }) + '\n'); },
|
|
reap: () => new Promise<void>((resolve, reject) => {
|
|
awaiting = { resolve, reject };
|
|
socket.write('{"type":"reap_descendants"}\n');
|
|
}),
|
|
};
|
|
}
|