Menu
Public repository / 439f0dcabf5cdf2b120c7724be895cf1df30507f
AkurAI-Framework / site/frontend/ai/components/display/terminal.js
Latest change 88d669a6b3c5464f8a947a66be0437a90424470f - feat(ai): add Display components — citation, link_preview, stats_display, terminal, weather_widget by Ólafur Búi Ólafsson
/**
* Terminal — command + output lines + exit code → styled terminal block.
* Payload: { command: string, lines: string[], exit_code?: number }
*/
function el(tag, cls) {
const node = document.createElement(tag);
if (cls) node.className = cls;
return node;
}
export const def = {
name: "terminal",
category: "Display",
title: "Terminal",
match(payload) {
return (
payload !== null &&
typeof payload === "object" &&
typeof payload.command === "string" &&
Array.isArray(payload.lines)
);
},
render(payload) {
const { command, lines, exit_code } = payload;
const wrap = el("div", "tc-display-terminal");
// Title bar
const bar = el("div", "tc-display-terminal__bar");
const dots = el("span", "tc-display-terminal__dots");
dots.innerHTML =
'<span style="background:#ff6b6b"></span>' +
'<span style="background:#f5b945"></span>' +
'<span style="background:#3ddc84"></span>';
bar.appendChild(dots);
const barLabel = el("span", "tc-display-terminal__bar-label muted small");
barLabel.textContent = "terminal";
bar.appendChild(barLabel);
wrap.appendChild(bar);
// Body (pre-formatted)
const pre = document.createElement("pre");
pre.className = "tc-display-terminal__body";
// Prompt + command line
const promptLine = document.createElement("div");
const prompt = el("span", "tc-display-terminal__prompt");
prompt.textContent = "$ ";
promptLine.appendChild(prompt);
const cmd = el("span", "tc-display-terminal__cmd");
cmd.textContent = command; // textContent is XSS-safe
promptLine.appendChild(cmd);
pre.appendChild(promptLine);
// Output lines
for (const line of lines) {
const lineEl = document.createElement("div");
lineEl.className = "tc-display-terminal__line";
lineEl.textContent = line; // XSS-safe
pre.appendChild(lineEl);
}
// Exit code row (only when present and non-zero, or explicitly 0)
if (exit_code !== undefined && exit_code !== null) {
const exitEl = el("div", "tc-display-terminal__exit muted small");
exitEl.textContent =
"[exit " + String(Number(exit_code)) + "]";
if (Number(exit_code) !== 0) {
exitEl.style.color = "var(--danger)";
}
pre.appendChild(exitEl);
}
wrap.appendChild(pre);
return wrap;
},
example: {
command: "bun run build",
lines: [
"$ bun run build",
" Building routes...",
" Compiled 42 pages in 180ms",
" Static assets copied: 7 files",
" Done.",
],
exit_code: 0,
},
};