Code Block
Command Output
A command and its output in one block: separate surfaces keep what you type apart from what the system answers, and the exit code sits in the footer.
- terminal
- output
- exit-code
- log
Preview
Use it with AI
- 1. Copy the link.
- 2. Write to your agent in your own words and drop the link into the sentence.
- 3. The agent opens the link and installs the component from the registry.
put this in the header: https://vibeui.ru/c/codeblock-012?lang=en
npm run registry:build✔ registry собран: 14 items
✔ public/r обновлён
Готово за 1.9 sexit 0успешно· 1.9 s
Show the full instructions
What the link says, spelled out. Use it when your agent cannot open links — paste this text instead.
# Install and place "codeblock-012" (Command Output) from VibeUI
## 1. Install first — do not skip, do not recreate
Run this exact command before writing any code:
npx shadcn@latest add https://vibeui.ru/r/codeblock-012.json
Registry item: https://vibeui.ru/r/codeblock-012.json
Installs to: components/vibeui/codeblock-012.tsx (the exact path follows this project's components.json aliases).
npm dependencies: none.
Registry dependencies: none.
Install it from the registry. Do not recreate it from the description,
do not substitute a similar component from another library, and do not
rewrite it to match the project's existing style.
## 2. What it is
A command and its output in one block: separate surfaces keep what you type apart from what the system answers, and the exit code sits in the footer.
The command on one surface, its output on another, exit code and duration in the footer. Zero dependencies, one file, no client JS.
## 3. How to use it
import { Codeblock012 } from "@/components/vibeui/codeblock-012"
<Codeblock012
command="npm run registry:build"
output={["✔ registry built", "Done"]}
exitCode={0}
duration="1.9 s"
/>
Read the installed file for the full prop list.
## 4. Where to place it
This is a small inline component. Put it exactly where the user asked,
inside the existing markup. Do not create a new page, section or
wrapper for it. If a similar control already sits in that spot,
replace it instead of adding a second one.
Placement: ___
(The user fills this line in. If it is still blank, ask where to put it
instead of guessing.)
## 5. Keep exactly as installed
- the local --vibeui-codeblock-012-* palette — do not swap it for your theme tokens
- the two surfaces: without a border between input and answer the block reads as one sheet
- the command and the output in separate pre elements — otherwise selection grabs both
- the prompt in ::before with user-select:none so the dollar sign stays out of the clipboard
- deriving the chip colour from exitCode itself: a status out of sync with the number misleads
- the dark block background — it defines the whole contrast logic of the surfaces
## 6. You may change
- the command through command and the output through output
- the exit code through exitCode
- the duration through duration
- the success and failure hues to match your palette
## 7. Rules
- Output is an array of lines, not text with ANSI codes: terminal colours are not parsed here.
- Trim a long log to a few lines on the caller's side: the block does not collapse by itself.
- A non-zero exitCode paints the footer as a failure, but the output text stays as given.
- Do not lift the CSS variables into globals.css: the component has to stay a single file.
## 8. Verify
- it renders with no console errors;
- it looks like the preview on the VibeUI page you copied this from;
- if it does not, you changed something listed in section 5 — put it back.For developers
npx shadcn@latest add https://vibeui.ru/r/codeblock-012.jsonhttps://vibeui.ru/r/codeblock-012.jsonКомпонент самодостаточен: один файл, без зависимостей, собственная палитра в локальных переменных --vibeui-codeblock-012-*. Серверный: хуков нет. Команда и вывод лежат в двух отдельных pre с разной подложкой, поэтому выделение мышью не смешивает ввод с ответом. Приглашение печатает ::before у команды и помечено user-select:none. Код возврата определяет цвет значка в подвале: ноль красится успехом, любое другое число — ошибкой, поэтому статус нельзя выставить вручную вразрез с числом.
Component source
The same file your agent installs. Here in case you would rather copy it by hand.
import type { ComponentPropsWithoutRef, CSSProperties } from "react"
export type Codeblock012Props = Omit<
ComponentPropsWithoutRef<"section">,
"children"
> & {
command?: string
output?: string[]
exitCode?: number
duration?: string
}
// Идея компонента: команда и её вывод — это две разные вещи, и они разведены
// подложкой. Команду можно выделить и вставить в терминал, не зацепив ответ;
// код возврата вынесен в подвал и красится по успеху, а не по угадыванию.
const STYLES = `
:where([data-vibeui-block="codeblock-012"]){
--vibeui-codeblock-012-bg:oklch(0.18 0.012 265);
--vibeui-codeblock-012-out-bg:oklch(0.23 0.014 265);
--vibeui-codeblock-012-fg:oklch(0.94 0.006 265);
--vibeui-codeblock-012-muted:oklch(0.7 0.014 265);
--vibeui-codeblock-012-border:oklch(1 0 0 / 12%);
--vibeui-codeblock-012-prompt:oklch(0.78 0.13 200);
--vibeui-codeblock-012-ok:oklch(0.84 0.15 152);
--vibeui-codeblock-012-ok-bg:oklch(0.5 0.13 152 / 24%);
--vibeui-codeblock-012-bad:oklch(0.76 0.18 25);
--vibeui-codeblock-012-bad-bg:oklch(0.5 0.16 25 / 24%);
--vibeui-codeblock-012-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
--vibeui-codeblock-012-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}
[data-vibeui-block="codeblock-012"]{
display:flex;flex-direction:column;
width:100%;max-width:32rem;box-sizing:border-box;overflow:hidden;
border:1px solid var(--vibeui-codeblock-012-border);border-radius:0.75rem;
background:var(--vibeui-codeblock-012-bg);color:var(--vibeui-codeblock-012-fg);
font-family:var(--vibeui-codeblock-012-font);
}
[data-vibeui-block="codeblock-012"] pre{margin:0;overflow-x:auto}
[data-vibeui-block="codeblock-012"] code{
display:block;min-width:max-content;
font-family:var(--vibeui-codeblock-012-mono);
font-size:0.8125rem;line-height:1.6;white-space:pre;
}
[data-vibeui-block="codeblock-012"] [data-part="command"]{padding:0.75rem 0.875rem}
[data-vibeui-block="codeblock-012"] [data-part="command"] code{padding-inline-start:1.125rem;position:relative}
[data-vibeui-block="codeblock-012"] [data-part="command"] code::before{
content:"$";position:absolute;left:0;
color:var(--vibeui-codeblock-012-prompt);font-weight:700;
user-select:none;-webkit-user-select:none;
}
/* Другая подложка — граница между тем, что вводят, и тем, что отвечают. */
[data-vibeui-block="codeblock-012"] [data-part="output"]{
padding:0.6875rem 0.875rem;
background:var(--vibeui-codeblock-012-out-bg);
border-top:1px solid var(--vibeui-codeblock-012-border);
color:var(--vibeui-codeblock-012-muted);
}
[data-vibeui-block="codeblock-012"] [data-part="foot"]{
display:flex;align-items:center;gap:0.5rem;
margin:0;padding:0.5rem 0.875rem;
background:var(--vibeui-codeblock-012-out-bg);
border-top:1px solid var(--vibeui-codeblock-012-border);
font-size:0.6875rem;color:var(--vibeui-codeblock-012-muted);
}
[data-vibeui-block="codeblock-012"] [data-part="code"]{
padding:0.125rem 0.4375rem;border-radius:999px;font-weight:700;
background:var(--vibeui-codeblock-012-bad-bg);color:var(--vibeui-codeblock-012-bad);
}
[data-vibeui-block="codeblock-012"] [data-part="code"][data-ok="true"]{
background:var(--vibeui-codeblock-012-ok-bg);color:var(--vibeui-codeblock-012-ok);
}
`
const OUTPUT = [
"✔ registry собран: 14 items",
"✔ public/r обновлён",
"Готово за 1.9 s",
]
/** Команда и её вывод: разные подложки, код возврата в подвале. */
export function Codeblock012({
command = "npm run registry:build",
output = OUTPUT,
exitCode = 0,
duration = "1.9 s",
className,
style,
...props
}: Codeblock012Props) {
const ok = exitCode === 0
return (
<>
<style href="vibeui-codeblock-012" precedence="medium">
{STYLES}
</style>
<section
{...props}
data-vibeui-block="codeblock-012"
className={className}
style={style as CSSProperties}
aria-label="Команда и её вывод"
>
<pre data-part="command">
<code>{command}</code>
</pre>
<pre data-part="output">
<code>{output.join("\n")}</code>
</pre>
<p data-part="foot">
<span data-part="code" data-ok={ok || undefined}>
exit {exitCode}
</span>
<span>{ok ? "успешно" : "с ошибкой"}</span>
<span>· {duration}</span>
</p>
</section>
</>
)
}