Skip to content

v1.2.0 - Phase 6: AI CLI Builder

Choose a tag to compare

@Arindam200 Arindam200 released this 24 Mar 20:36

Phase 6: AI CLI Builder

TermUI v1.2.0 adds first-class primitives for building AI-powered terminal applications. Three new package exports, 13 new components and hooks, and a conversation persistence utility.

New exports

Export Contents
termui/components/ai All AI UI components
termui/ai useChat, useCompletion hooks
termui/conversation-store createConversationStore

Tier 1 - Core Primitives

StreamingText
Renders LLM token streams token-by-token. Accepts a controlled text prop, an AsyncIterable<string> via stream, a blinking cursor, and a animate/speed typing mode for pre-buffered responses.

<StreamingText stream={tokenStream} cursor="▌" onComplete={(full) => save(full)} />

Markdown streaming mode
New streaming and cursor props on the existing component. Partial code fences are closed gracefully so the component never crashes mid-stream.

<Markdown streaming cursor="▌">{partialMarkdownFromLLM}</Markdown>

DiffView
Unified, split, and inline diff views with an internal LCS algorithm (no added dependency). Supports context lines, showLineNumbers, coloured +/- lines, and @@ hunk headers.

<DiffView oldText={original} newText={modified} filename="src/index.ts" mode="unified" showLineNumbers />

Tier 2 - Chat UI Components

ChatThread + ChatMessage — Role-based message styling, animated ... typing indicator, collapsible system messages, autoScroll.

ToolCall — Status icons for pending/running/success/error, live elapsed timer, collapsible args and result.

ThinkingBlock — Collapsible chain-of-thought with token count and streaming indicator.

ToolApproval — Risk-level border colour (green/yellow/red), y/n/a keybindings, countdown auto-deny.


Tier 3 - AI Integration Layer

useChat + useCompletion — Provider-agnostic streaming hooks. Supports Anthropic, OpenAI, Ollama, and a custom fetchFn. tokenUsage is populated from each provider's native usage events.

import { useChat } from 'termui/ai';

const { messages, sendMessage, isStreaming, tokenUsage } = useChat({
  provider: 'anthropic',
  model: 'claude-sonnet-4-6',
  apiKey: process.env.ANTHROPIC_API_KEY,
});

TokenUsage + ContextMeter — Compact cost display with warn/critical colour thresholds.

ModelSelector — Provider grouping, context window size display, built on Select.

FileChange — File list with M/A/D icons, keyboard navigation, and inline DiffView per file.


Tier 4 - Ecosystem

createConversationStore — JSONL/JSON persistence with save/load/list/delete/search. Auto-titles from the first user message.

import { createConversationStore } from 'termui/conversation-store';

const store = createConversationStore({ dir: '~/.myapp/conversations', format: 'jsonl' });
await store.save(id, messages);

Bug Fixes

  • useChat history: replaced the setMessages functional-updater capture pattern with a messagesRef updated synchronously; correct message list is sent on every turn including the first
  • tokenUsage never populated: wired setTokenUsage into all three provider streams via native usage events
  • DiffView inline mode was identical to unified; implemented a proper InlineView
  • DTS build TS2307 for optional peer SDKs: dynamic imports now use a variable specifier so tsc skips static module resolution
  • tsconfig.json missing path entries for new subpaths fixed