import { appendFileSync } from "node:fs"; import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; function appendResultEntry( type: "assistant" | "final" | "toolResult", message: unknown ): void { const outputFile = process.env.PI_SUBAGENT_OUTPUT_FILE; if (!outputFile) { throw new Error( "PI_SUBAGENT_OUTPUT_FILE is required for Herdr child result capture." ); } appendFileSync( outputFile, `${JSON.stringify({ isSidechain: true, agentId: process.env.PI_SUBAGENT_ID, type, message, timestamp: new Date().toISOString(), cwd: process.cwd(), })}\n`, "utf-8" ); } export default function (pi: ExtensionAPI): void { let lastAssistantMessage: unknown; let finalWritten = false; pi.on("message_end", (event) => { if (finalWritten) { return; } if (event.message.role === "assistant") { lastAssistantMessage = event.message; appendResultEntry("assistant", event.message); } }); pi.on("agent_end", (event, ctx) => { if (finalWritten) { return; } const finalAssistantMessage = [...event.messages] .reverse() .find((message) => message.role === "assistant"); appendResultEntry( "final", finalAssistantMessage ?? lastAssistantMessage ?? null ); finalWritten = true; ( ctx as | { ui?: { notify?: (message: string, level: "warning") => void } } | undefined )?.ui?.notify?.( "Herdr child pane is now manual and untracked by the parent.", "warning" ); }); pi.on("tool_execution_end", (event) => { if (finalWritten) { return; } appendResultEntry("toolResult", { role: "toolResult", toolCallId: event.toolCallId, toolName: event.toolName, content: event.result, isError: event.isError, timestamp: Date.now(), }); }); }