import type { ExtensionAPI } from '@earendil-works/pi-coding-agent'; import net from 'node:net'; async function brokerRequest(payload: Record): Promise> { const socketPath = process.env['GATE0_BROKER_SOCKET']; if (!socketPath) throw new Error('GATE0_BROKER_SOCKET missing'); return await new Promise((resolve, reject) => { const socket = net.createConnection(socketPath); let buffer = ''; socket.setEncoding('utf8'); socket.on('connect', () => socket.write(`${JSON.stringify(payload)}\n`)); socket.on('data', (chunk) => { buffer += chunk; const newline = buffer.indexOf('\n'); if (newline < 0) return; socket.end(); resolve(JSON.parse(buffer.slice(0, newline)) as Record); }); socket.on('error', reject); }); } export default function register(pi: ExtensionAPI) { pi.on('session_start', async () => { const response = await brokerRequest({ action: 'resolve-hook', runtime: 'pi-extension' }); if (response['decision'] !== 'ACCEPT') { throw new Error(`P1 broker rejected Pi extension ancestry: ${response['reason']}`); } }); pi.registerCommand('gate0-p1-ready', { description: 'Return only after the P1 session_start ancestry hook completed', handler: async () => undefined, }); }