import { isBashToolResult, type ExtensionAPI } from "@earendil-works/pi-coding-agent"; export default function testStatusExtension(pi: ExtensionAPI) { // After every tool execution, check if tests just ran pi.on("tool_result", async (event, ctx) => { // Only care about bash commands if (!isBashToolResult(event)) return; const command: string = event.input.command; // Only care about test commands if (!command.includes("npm test") && !command.includes("vitest") && !command.includes("npx vitest")) { return; } const output = event.content[0]?.text ?? ""; const theme = ctx.ui.theme; // Detect pass/fail from vitest summary output const testsPassed = /Tests\s+.+passed/.test(output) && !/Tests\s+.+failed/.test(output); const testsFailed = /Tests\s+.+failed/.test(output) || event.details?.exitCode !== 0; if (testsPassed) { // Extract summary line for inline detail (e.g., "1 passed (242ms)") const summaryLine = output .split("\n") .find((line: string) => /Test Files\s+.+passed/.test(line)); const summary = summaryLine?.trim() ?? "All tests passed"; ctx.ui.setWidget("test-status", [ `${theme.fg("success", "●")} ${theme.fg("text", summary)}`, ]); } else if (testsFailed) { const summaryLine = output .split("\n") .find((line: string) => /Tests\s+.+failed/.test(line)); const summary = summaryLine?.trim() ?? "Tests failed"; ctx.ui.setWidget("test-status", [ `${theme.fg("error", "●")} ${theme.fg("text", summary)}`, ]); } }); }