import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent"; export default function (pi: ExtensionAPI) { pi.on("session_start", async (_event, ctx) => { // Fire-and-forget: do not block session start on the test run, and let the // "test-balls:record" event land after every extension's session_start handler // has run (project extensions load before global ones, so emitting synchronously // from this handler would race test-balls' runs reset). void runMakeTest(pi, ctx).catch((error) => { console.error("run_make_test:", error); }); }); } async function runMakeTest(pi: ExtensionAPI, ctx: ExtensionContext): Promise { // Record exactly one ball per run, even if UI reporting below fails. let recorded = false; const record = (pass: boolean) => { if (recorded) return; recorded = true; pi.events.emit("test-balls:record", { pass, command: "make test", ts: Date.now() }); }; try { const { stdout, stderr, code } = await pi.exec("make", ["test"]); record(code === 0); const output = stdout + stderr; if (code === 0) { ctx.ui.notify("make test passed", "info"); } else { ctx.ui.notify(`make test failed (exit ${code})`, "error"); } // Also send the output as a message so it's visible in the session pi.sendMessage({ customType: "run-make-test", content: [ { type: "text", text: `Here's the result of running \`make test\`:\n\n\`\`\`\n${output}\`\`\``, }, ], display: true, }, { deliverAs: "followUp" }); } catch (error) { record(false); const message = error instanceof Error ? error.message : String(error); pi.sendMessage({ customType: "run-make-test", content: [ { type: "text", text: `Error running make test: ${message}` }, ], display: true, }, { deliverAs: "followUp" }); } }