36 / 122 · Tool use
Code runner
A snippet with a run button, and the output it produced attached below it.
typescript38ms
const queue = createMessageQueue(driver);
queue.enqueue("also add a changeset");
console.log(queue.size);output1→ drains when the run settles
Installation
npx shadcn@latest add "@assistant-ui/elements-code-runner"
Usage
import { CodeRunner } from "@/components/elements/code-runner";
<CodeRunner
language="typescript"
code={code}
state="ok"
output={["1"]}
durationMs={38}
onRun={run}
/>Props
language*stringLanguage label above the snippet.
code*stringThe snippet. Rendered as plain mono; wrap it yourself for highlighting.
state*"idle" | "running" | "ok" | "error"idle hides the output pane entirely; error tints the output red.
output*string[]Output lines, revealed in sequence.
durationMsnumberHow long the run took, printed once it settles.
onRun() => voidCalled when the run control is pressed.
classNamestringExtra classes merged onto the root.
Source
code-runner.tsx"use client";
import { Loader2Icon, PlayIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import { ghostButton, mono, paper } from "./surfaces";
export type RunState = "idle" | "running" | "ok" | "error";
export function CodeRunner({
language,
code,
state,
output,
durationMs,
onRun,
className,
}: {
language: string;
code: string;
state: RunState;
output: readonly string[];
durationMs?: number;
onRun?: () => void;
className?: string;
}) {
return (
<div
className={cn(
paper,
"flex w-full max-w-md flex-col overflow-hidden rounded-2xl",
className,
)}
>
<div className="flex items-center gap-2 px-3.5 py-2">
<span className={cn(mono, "text-foreground/35 min-w-0 flex-1")}>
{language}
</span>
{durationMs !== undefined && state !== "running" && (
<span
className={cn(mono, "text-foreground/30 shrink-0 tabular-nums")}
>
{durationMs}ms
</span>
)}
<button
type="button"
aria-label="Run this snippet"
onClick={onRun}
disabled={state === "running"}
className={cn(
ghostButton,
"size-7 shrink-0 disabled:pointer-events-none",
)}
>
{state === "running" ? (
<Loader2Icon className="size-3.5 animate-spin motion-reduce:animate-none" />
) : (
<PlayIcon className="size-3.5 translate-x-px" />
)}
</button>
</div>
<pre className="border-foreground/[0.07] overflow-x-auto border-t px-3.5 py-2.5 font-mono text-xs leading-relaxed">
<code className="text-foreground/75">{code}</code>
</pre>
{state !== "idle" && (
<div className="border-foreground/[0.07] fade-in animate-in flex flex-col border-t px-3.5 py-2.5 duration-300">
<span className={cn(mono, "text-foreground/30 pb-1")}>output</span>
{output.map((line, i) => (
<span
key={`${i}-${line}`}
className={cn(
"fade-in animate-in fill-mode-both font-mono text-xs leading-relaxed whitespace-pre",
state === "error"
? "text-red-600 dark:text-red-400"
: "text-foreground/70",
)}
style={{ animationDelay: `${i * 80}ms` }}
>
{line}
</span>
))}
{state === "running" && (
<span
aria-hidden
className="bg-foreground/40 h-[1em] w-[2px] animate-pulse rounded-full motion-reduce:animate-none"
/>
)}
</div>
)}
</div>
);
}