import { copyToClipboard, type ExtensionAPI, type SessionEntry } from "@earendil-works/pi-coding-agent"; import { findSections } from "./sections.js"; function latestAssistantText(entries: SessionEntry[]): string | undefined { for (let index = entries.length - 1; index >= 0; index--) { const entry = entries[index]; if (!entry || entry.type !== "message" || entry.message.role !== "assistant") continue; const text = entry.message.content .filter((block) => block.type === "text") .map((block) => block.text) .join("\n") .trim(); if (text) return text; } return undefined; } export default function smartCopy(pi: ExtensionAPI) { pi.registerCommand("smart-copy", { description: "copy all or one markdown section from the latest response", handler: async (_args, ctx) => { const response = latestAssistantText(ctx.sessionManager.getBranch()); if (!response) { ctx.ui.notify("no assistant response to copy", "warning"); return; } const sections = findSections(response); let text = response; let name = "response"; if (sections.length > 0 && ctx.hasUI) { const choices = ["entire response", ...sections.map((section, index) => `${index + 1}. ${section.label}`)]; const choice = await ctx.ui.select("copy which section?", choices); if (!choice) return; const sectionIndex = choices.indexOf(choice) - 1; if (sectionIndex >= 0) { text = sections[sectionIndex]!.text; name = sections[sectionIndex]!.label; } } try { await copyToClipboard(text); ctx.ui.notify(`copied ${name}`, "info"); } catch (error) { ctx.ui.notify(`couldn't copy: ${error instanceof Error ? error.message : String(error)}`, "error"); } }, }); }