Add copy buttons to code blocks and tool input and output
This commit is contained in:
@@ -39,6 +39,23 @@ export function replace(el: Element, ...children: Child[]): void {
|
||||
append(el, ...children);
|
||||
}
|
||||
|
||||
export function copyable(pre: HTMLPreElement): HTMLElement {
|
||||
const button = h("button", { type: "button", class: "copy", title: "Copy to the clipboard" }, "copy");
|
||||
button.onclick = async () => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(pre.textContent ?? "");
|
||||
} catch (err) {
|
||||
void showAlert(errorText(err));
|
||||
return;
|
||||
}
|
||||
button.textContent = "copied";
|
||||
setTimeout(() => {
|
||||
button.textContent = "copy";
|
||||
}, 1500);
|
||||
};
|
||||
return h("div", { class: "copyable" }, pre, button);
|
||||
}
|
||||
|
||||
export function ago(iso: string): string {
|
||||
const seconds = Math.round((Date.now() - Date.parse(iso)) / 1000);
|
||||
if (seconds < 60) {
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { h } from "./dom.js";
|
||||
import { copyable, h } from "./dom.js";
|
||||
import { diagram } from "./mermaid.js";
|
||||
import { taskStyle } from "./taskcolor.js";
|
||||
|
||||
@@ -50,7 +50,7 @@ function blocks(lines: string[], opts: Options): Block[] {
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
out.push(f[2]!.toLowerCase() === "mermaid" ? diagram(body.join("\n")) : h("pre", { class: "md-code" }, h("code", {}, body.join("\n"))));
|
||||
out.push(f[2]!.toLowerCase() === "mermaid" ? diagram(body.join("\n")) : copyable(h("pre", { class: "md-code" }, h("code", {}, body.join("\n")))));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
import { get, post, type AgentSession, type ByreEvent, type Participant, type Schemas, type Snapshot } from "./api.js";
|
||||
import { ago, errorText, h, replace, showAlert, showConfirm } from "./dom.js";
|
||||
import { ago, copyable, errorText, h, replace, showAlert, showConfirm } from "./dom.js";
|
||||
import { markdown } from "./markdown.js";
|
||||
import { previewURL } from "./preview.js";
|
||||
import { reviewCounts } from "./reviews.js";
|
||||
@@ -837,7 +837,7 @@ function renderToolCall(p: Record<string, unknown>, ctx: Ctx): HTMLElement {
|
||||
"details",
|
||||
{ class: "tool" },
|
||||
h("summary", {}, subagentTag(parentOf(p), ctx), h("span", { class: "tool-name" }, String(p["name"])), " ", h("span", { class: "tool-brief" }, toolBrief(p["input"], ctx.root()))),
|
||||
h("pre", { class: "tool-input" }, JSON.stringify(p["input"], null, 2)),
|
||||
copyable(h("pre", { class: "tool-input" }, JSON.stringify(p["input"], null, 2))),
|
||||
result,
|
||||
);
|
||||
}
|
||||
@@ -982,7 +982,7 @@ function renderEvent(ev: ByreEvent, ctx: Ctx): HTMLElement | null {
|
||||
|
||||
case "agent.tool_result": {
|
||||
const target = ctx.tools.get(String(p["tool_use_id"]));
|
||||
const body = h("pre", {}, resultText(p["content"]));
|
||||
const body = copyable(h("pre", {}, resultText(p["content"])));
|
||||
if (!target) {
|
||||
return h("div", { class: "tool-result orphan" }, body);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user