import type { Artifact } from "@danypops/papyrus"; import type { ExtensionCommandContext, Theme } from "@earendil-works/pi-coding-agent"; import { showArtifactBrowser, showArtifactDetails } from "../artifact/artifact-browser.ts"; import { DOC_STATUS_PRESENTATION } from "../artifact/artifact-status-presentation.ts"; import { parseLabelInput } from "../artifact/binder-navigation.ts"; import { callService } from "../service-client.ts"; const DOC_ACTIONS: Record = { draft: ["Activate", "Archive"], active: ["Archive"], archived: ["Reopen"], }; const DOC_RELATIONS = ["references", "documents", "supersedes", "relates_to", "contains", "part_of"]; export function documentRowMeta(document: Artifact, theme: Theme): string { const subtype = document.subtype ? theme.fg("accent", document.subtype) : ""; return [subtype, document.labels.join(", ")].filter(Boolean).join(" · "); } export async function showDocs(ctx: ExtensionCommandContext): Promise { await showArtifactBrowser(ctx, { kind: "doc", title: "Documents", listOperation: "docs.list", statusOrder: ["draft", "active", "archived"], presentation: DOC_STATUS_PRESENTATION, hierarchical: true, rowMeta: documentRowMeta, actions: (document) => ["Show details", "Edit", "Link artifact", ...(DOC_ACTIONS[document.status] ?? [])], handleAction: async (choice, document, commandCtx) => { if (choice === "Show details") { await showArtifactDetails(commandCtx, document.id, "docs.show"); return; } if (choice === "Edit") { const current = await callService, Artifact>("docs.show", { id: document.id }); const title = await commandCtx.ui.input("Title:", current.title); if (title === undefined) return; // canceled const body = await commandCtx.ui.input("Body:", current.body); if (body === undefined) return; // canceled const labels = await commandCtx.ui.input("Direct labels (comma-separated):", current.labels.join(", ")); if (labels === undefined) return; // canceled const updated = await callService, Artifact>("docs.update", { id: document.id, title, body, labels: parseLabelInput(labels), }); commandCtx.ui.notify(`Updated "${updated.title}"`, "info"); return; } if (choice === "Link artifact") { const targetId = await commandCtx.ui.input("Target artifact id:", ""); if (!targetId) return; const relation = await commandCtx.ui.select("Relation", DOC_RELATIONS); if (!relation) return; await callService("docs.link", { id: document.id, relation, target_id: targetId }); commandCtx.ui.notify(`Linked "${document.title}" via ${relation}`, "info"); return; } const operation = choice === "Activate" ? "docs.activate" : choice === "Archive" ? "docs.archive" : choice === "Reopen" ? "docs.reopen" : undefined; if (operation) { const updated = await callService, Artifact>(operation, { id: document.id }); commandCtx.ui.notify(`${updated.title} → [${updated.status}]`, "info"); } }, }); }