Render Mermaid diagrams and worktree images in agent Markdown

This commit is contained in:
Ian Gulliver
2026-10-15 07:27:17 -07:00
parent 1f44bc6d91
commit 4ca6f88861
26 changed files with 5613 additions and 227 deletions
+10 -9
View File
@@ -1,7 +1,8 @@
import { post, type Attachment, type InboxItem, type InboxResponseCreate } from "./api.js";
import { mountChanges } from "./changes.js";
import { ago, errorText, h, replace, showAlert } from "./dom.js";
import { inlineMarkdown, markdown } from "./markdown.js";
import { image, inlineMarkdown, markdown } from "./markdown.js";
import { diagram } from "./mermaid.js";
import { findTask, onEach, state } from "./state.js";
type Scope = "all" | "project" | "task";
@@ -320,14 +321,14 @@ function card(item: InboxItem): HTMLElement {
case "question":
replace(
body,
markdown(String(p["context"]), "md context", choice),
markdown(String(p["question"]), "md question"),
h("p", { class: "why" }, h("strong", {}, "Blocked on: "), inlineMarkdown(String(p["why_blocked"]))),
attachments((p["attachments"] as Attachment[] | undefined) ?? []),
markdown(String(p["context"]), "md context", { choice, taskId: item.task_id }),
markdown(String(p["question"]), "md question", { taskId: item.task_id }),
h("p", { class: "why" }, h("strong", {}, "Blocked on: "), inlineMarkdown(String(p["why_blocked"]), { taskId: item.task_id })),
attachments((p["attachments"] as Attachment[] | undefined) ?? [], item.task_id),
);
break;
case "report":
replace(body, markdown(String(p["text"] ?? ""), "md summary"));
replace(body, markdown(String(p["text"] ?? ""), "md summary", { taskId: item.task_id }));
break;
case "session_error":
replace(body, h("p", { class: "error-text" }, String(p["error"])));
@@ -357,7 +358,7 @@ function thread(item: InboxItem): HTMLElement | null {
);
}
function attachments(list: Attachment[]): HTMLElement | null {
function attachments(list: Attachment[], taskId: string | undefined): HTMLElement | null {
if (list.length === 0) {
return null;
}
@@ -374,9 +375,9 @@ function attachments(list: Attachment[]): HTMLElement | null {
case "diff":
return h("li", {}, "diff ", h("code", {}, a.ref ?? ""), caption);
case "image":
return h("li", {}, a.image?.startsWith("data:image/") ? h("img", { src: a.image, alt: a.caption ?? "" }) : null, caption);
return h("li", {}, a.image || a.path ? image(a.image || a.path!, a.caption ?? "", taskId) : null, caption);
case "diagram":
return h("li", {}, h("pre", { class: "mermaid-source" }, a.mermaid ?? ""), caption);
return h("li", {}, diagram(a.mermaid ?? ""), caption);
case "task":
return h("li", {}, h("a", { href: `#/task/${a.task_id}` }, "task ", a.task_id ?? ""), caption);
case "snapshot":