@comma-agents/tui
Components
Ink component inventory for the TUI — composable terminal UI components following a container and render split pattern.
The TUI is built from composable Ink (React-for-terminal) components. Every component follows a container/render split -- the container holds state and hooks, and a companion *Render function is a pure presentational component that receives resolved props.
All components consume theme tokens through per-component hooks (e.g. useFrameTheme()) produced by defineTheme.
import { Frame, MessageList, StatusBar, ChatTextArea } from "@comma-agents/tui";
<Frame footer={<StatusBar status="idle" />}>
<MessageList messages={chat.messages} />
<ChatTextArea
strategies={strategies}
onSubmit={(strategyPath, input) => startStrategy(strategyPath, input)}
/>
</Frame>Component Inventory
Shell & Layout
| Component | Purpose |
|---|---|
| Frame | Root layout shell with tab bar, terminal resize tracking, pinned footer |
| BorderedPanel | Panel with a text label embedded into the top border |
| Separator | Horizontal separator line -- fills parent width or fixed-length |
| Hide | Responsive visibility toggle -- hide below/above a breakpoint or column count |
| MeasuredBox | Self-measuring Box wrapper with render-prop dimensions |
Input
| Component | Purpose |
|---|---|
| TextAreaInput | Multi-line text input with word wrap, cursor navigation, scrollbar, mouse wheel |
| ChatTextArea | Strategy-aware prompt input -- wraps TextAreaInput with Tab-to-cycle strategy selection |
| SearchInput | Single-line search input with caret prompt and placeholder |
| Button | Interactive button with focus, hover, click, and disabled state support |
Chat
| Component | Purpose |
|---|---|
| MessageList | Chat message display -- role-colored messages, scroll-to-bottom, streaming cursor |
| StatusBar | Chat status indicator -- spinner, status label, error display |
| PermissionPrompt | Sandbox permission request prompt with action buttons |
Scrolling
| Component | Purpose |
|---|---|
| ScrollableView | Variable-height scrollable container with per-row measurement and mouse wheel |
| ScrollableList | Generic single-selection list with arrow-key navigation and scrollbar |
| Scrollbar | Single-column vertical scrollbar -- presentational |
Overlays
| Component | Purpose |
|---|---|
| Modal | Full-screen overlay dialog with backdrop dimming |
| CommandPalette | Full command palette with searchable list and sub-page navigation |
| CodeView | Syntax-highlighted code block powered by Shiki |
Decoration
| Component | Purpose |
|---|---|
| StrategyPicker | Strategy selection menu using ink-select-input |
| TitleIcon | Animated ASCII art logo with responsive text banner |
Architecture
Components are organized under src/components/, each in its own directory:
ComponentName/
├── index.ts # barrel export
├── ComponentName.tsx # container + render
├── ComponentName.theme.ts # useComponentNameTheme() hook
├── ComponentName.types.ts # prop interfaces (if complex)
├── ComponentName.test.tsx # tests
├── ComponentName.stories.tsx # Storybook stories
└── ComponentName.constants.ts # (optional)The barrel export at src/components/index.ts re-exports all components, types, and theme hooks.