suiss/ui
  • Docs
  • Components
  • Patterns
  • Interactions
  • Charts
  • Blocks
  • AI
GitHubCreate
DocsComponentsPatternsInteractionsChartsBlocksAICreate
AI21
  • Overview
Conversation
  • Chat
  • Message
  • Prompt Input
  • Suggestion
  • Model Selector
  • Context
  • Checkpoint
  • Inline Citation
Agent steps
  • Chain of Thought
  • Reasoning
  • Tool
  • Confirmation
  • Task
  • Plan
  • Queue
  • Subagent
  • Sources
Output
  • Terminal
  • Stack Trace
  • Test Results
  • File Tree

suiss/ui · AI

Terminal

A shell command an agent runs, such as a lint, a test run or a build, with its output underneath.

import { TerminalIcon } from "@phosphor-icons/react"
import { Bubble, BubbleContent } from "@/components/ui/bubble"
import { CodeBlock, CodeBlockContent } from "@/components/ui/code-block"
import { Message, MessageContent } from "@/components/ui/message"
import {
  Trace,
  TraceCollapsible,
  TraceCollapsibleContent,
  TraceCollapsibleTrigger,
  TraceIcon,
  TraceLine,
  TraceTitle,
} from "@/components/ui/trace"

const commands = [
  {

Terminal is a shell command the agent runs, such as a lint, a test run or a build. The row shows the command, and its output sits underneath in a Code Block.

Terminal is built with Trace, with a TraceCollapsible for each command.

Installation

Terminal is built with the Trace and Code Block components.

$ pnpm dlx shadcn@latest add @esuiss/trace @esuiss/code-block

Or use the suiss/ui CLI:

$ pnpm dlx @esuiss/ui@latest add trace code-block

Usage

import { CodeBlock, CodeBlockContent } from "@/components/ui/code-block"
import {
  Trace,
  TraceCollapsible,
  TraceCollapsibleContent,
  TraceCollapsibleTrigger,
  TraceIcon,
  TraceLine,
  TraceTitle,
} from "@/components/ui/trace"
<Trace>
  <TraceCollapsible>
    <TraceCollapsibleTrigger>
      <TraceLine>
        <TraceIcon>
          <TerminalIcon />
        </TraceIcon>
        <TraceTitle>Ran pnpm build</TraceTitle>
      </TraceLine>
    </TraceCollapsibleTrigger>
    <TraceCollapsibleContent>
      <CodeBlock size="sm">
        <CodeBlockContent wrap className="max-h-64">
          {output}
        </CodeBlockContent>
      </CodeBlock>
    </TraceCollapsibleContent>
  </TraceCollapsible>
</Trace>

Examples

Exit code

A command that exits with any code other than 0 failed. Set status="error" and open the row so the output is visible.

import { TerminalIcon } from "@phosphor-icons/react"
import { CodeBlock, CodeBlockContent } from "@/components/ui/code-block"
import {
  Trace,
  TraceCollapsible,
  TraceCollapsibleContent,
  TraceCollapsibleTrigger,
  TraceIcon,
  TraceLine,
  TraceTitle,
} from "@/components/ui/trace"

const LINT_OUTPUT = `> acme-chat@0.1.0 lint
> eslint .

app/api/chat/route.ts
CommandstatusTitle
Running"running"Running pnpm build
Exited with 0—Ran pnpm build
Exited with another code"error"pnpm lint exited with code 1

Open while running

Open the row once the first output arrives, so the output is visible while the command runs, and let the reader's choice win after that. See Trace.

AI SDK

A tool result arrives only once the command exits. To stream the output while it runs, write it from the tool as a data part with the tool call's id. The AI SDK replaces a data part that has the same id, so the output grows in place.

app/api/chat/route.ts
writer.write({
  type: "data-terminal",
  id: toolCallId,
  data: { output },
})

On the client, find the data part that matches each tool part.

function getOutput(message: ChatMessage, toolCallId: string) {
  for (const part of message.parts) {
    if (part.type === "data-terminal" && part.id === toolCallId) {
      return part.data.output
    }
  }
  return ""
}

API Reference

See Trace and Code Block.

Accessibility

  • Say the result in the title, not only with color: "Ran pnpm build" or "pnpm lint exited with code 1".
  • Each row is a button with aria-expanded, and the output is reachable by keyboard so long lines can be scrolled.
import { TerminalIcon } from "phosphor-react-native"
import { View } from "react-native"
import { Bubble, BubbleContent } from "@/components/ui/bubble"
import { CodeBlock, CodeBlockContent } from "@/components/ui/code-block"
import { Icon } from "@/components/ui/icon"
import { Message, MessageContent } from "@/components/ui/message"
import { Text } from "@/components/ui/text"
import { Trace, TraceCollapsible, TraceCollapsibleContent, TraceCollapsibleTrigger, TraceDescription, TraceIcon, TraceLine, TraceTitle } from "@/components/ui/trace"

export function AiTerminalExample() {
  return (
    <View className="w-full gap-4">
      <Message align="end">
        <MessageContent>
          <Bubble variant="muted">
            <BubbleContent>Run the checks, then build the app.</BubbleContent>
import EsuissUI
import PhosphorSwift
import SwiftUI

struct TerminalExample: View {
  var body: some View {
    VStack(alignment: .leading, spacing: 16) {
      Message(align: .end) {
        MessageContent {
          Bubble(variant: .muted, align: .end) { BubbleContent("Run the checks, then build the app.") }
        }
      }
      Trace {
        TraceLine {
          TraceIcon { Ph.terminal.regular }
          TraceTitle(verbatim: "Ran pnpm lint")
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.adamglin.PhosphorIcons
import com.adamglin.phosphoricons.Regular
import com.adamglin.phosphoricons.regular.Terminal
import com.esuiss.ui.components.Bubble
import com.esuiss.ui.components.BubbleContent
import com.esuiss.ui.components.BubbleVariant
import com.esuiss.ui.components.CodeBlock
import com.esuiss.ui.components.CodeBlockContent
import com.esuiss.ui.components.CodeBlockSize
import com.esuiss.ui.components.Icon

Terminal on mobile is built from the same parts as on the web: Trace, Code Block, Message, Bubble. The example above is a static demo; connect it to your agent by rendering the same parts from your messages.

Installation

$ pnpm dlx @esuiss/ui@latest add trace code-block message bubble
$ pnpm dlx @esuiss/ui@latest add trace code-block message bubble --platform swift
$ pnpm dlx @esuiss/ui@latest add trace code-block message bubble --platform kotlin

API Reference

See Trace, Code Block, Message, Bubble.

NextStack TracePreviousSources

On this page

  1. 01Installation
  2. 02Usage
  3. 03Examples
    • Exit code
    • Open while running
  4. 04AI SDK
  5. 05API Reference
  6. 06Accessibility
  7. 07Installation
  8. 08API Reference