Changelog
Unseen UI is an experimental alpha. Prereleases are published on npm under the alpha tag; pin exact versions. Newest first.
0.1.0-alpha.11 — 3 November 2026
Upgrade notes
- Status text is capitalised. Badges and status lines read "Connected", "Passed", "Permission requested" and "Medium risk" instead of the raw values ("connected", "Permission: requested", "medium risk"). Tests that look for the old text need the new words.
- ModelSelector shows its search field only for more than seven models; pass
searchableto keep it. Provider headings show only when models come from more than one provider. - Compact ThreadList rows are 36px including their borders, 1px apart (were 38px and 4px).
- WorkspaceShell panes take their padding and scrollbar room from
--ai-workspace-pane-paddingand--ai-workspace-pane-gutter. If you overrode the old 4px padding with a more specific selector, set the variables instead. - Chat replies in the chat message variant render Markdown at the message size (16px) rather than the interface size (14px).
- PromptInput no longer shows "Shift + Enter for a new line" by default; screen readers still hear it. Pass
hintto show a line. - The assistant icon (
AIIcon name="assistant") is a speech bubble instead of a magic wand. Chat and ModelControls headers no longer show a decorative icon before their titles. - RunBoard with
variant="list"shows runs as rows divided by lines, with a sentence-case group heading, instead of a bordered card per run. Board and compact variants are unchanged. - DateRangePicker joins a selected range with an en dash ("Thursday, February 1, 2024 – Saturday, February 3, 2024", was an em dash) and reads "Thursday, February 1, 2024. Choose the end date" while picking.
- Overlay content has no wrapper div. Modal, AlertDialog, Popover, Tooltip, DropdownMenu, ContextMenu and Select content now carry the theme scope (
data-ai-theme,data-appearance) themselves instead of sitting inside an extra div in the portal. Selectors that reached the content through that wrapper need updating. - Closed menus fade out. Force-mounted DropdownMenu and ContextMenu content is hidden by its exit animation and made inert, instead of
display: none. - Plainer status messages. About 150 messages people see in components no longer mention a "host", "receipt", "acknowledgement" or "authoritative snapshot". For example "Waiting for host acknowledgement." is now "Waiting for confirmation.", and "Host rejected the edit: …" is now "Edit rejected: …". The meaning of each message is unchanged. Tests that match the old wording need the new words.
- Icons default to 15px, the grid the built-in Radix icons are drawn on, so their edges stay sharp. Pass
sizeto IconsProvider or AIIcon for another size.
Changes
-
Chat:
onEditlets people rewrite a sent message;branchesandonBranchChangeshow "‹ 1/2 ›" to switch between versions after an edit or a regenerate;feedbackandonFeedbackrate any reply;renderMessageActionsadds actions such as Read aloud;emptyContentreplaces the start screen. Copy and rating now appear under every finished reply (earlier ones on hover), with Regenerate on the last. -
Messages: new
reasoningandfileparts. Reasoning shows as a "Thinking…" disclosure that collapses when the answer arrives; attached images show as thumbnails and other files as a chip. The AI SDK mapping fills them in; reasoning stays hidden unless you passreasoning: 'show', and only http(s) or base64 PNG, JPEG, GIF and WebP images are shown inline. -
Sources: web sources from the AI SDK follow the reply, and neighbouring sources share one row of chips.
-
Modal:
triggeris optional, for dialogs opened from a menu or a keyboard shortcut. Without a trigger, closing returns focus to whatever opened it, whether the host closes the Modal or stops rendering it. -
WorkspaceShell:
navigationMode="responsive"adds a navigation toggle. Wide layouts collapse the navigation column; narrow ones show it as a drawer that takes focus, closes on Escape, the scrim or a followed link, and returns focus to the toggle. Control it withnavigationOpenandonNavigationOpenChange;navigationBreakpointsets the width. Crossing the breakpoint closes the navigation on the way down, so phones start on the content, and reopens it on the way up.headerPlacement="main"puts the header above the main content only, with navigation running the full height, as in chat apps. -
PromptInput and Chat:
commandsandmentions. Typing "/" at the start of a message, or "@" after a space, opens a list above the composer, filtered as you type: arrow keys move, Enter or Tab picks, Escape closes, and the textarea announces it as an autocomplete list. A command removes the typed "/word" and callsonCommandwith the remaining message; a mention inserts "@label " and callsonMention.onMentionQueryChangelets you search on your side, for example over files. -
Chat and Message:
messageVariant="chat"on Chat (orvariant="chat"on Message) shows your messages as right-aligned bubbles and replies as plain text, without avatars or speaker labels on screen; the speaker stays available to screen readers, and actions sit under the bubble. The "/" and "@" list now opens below the composer when there is no room above, and lists one option per line. -
WorkspaceShell: scrolling panes are positioned, so absolutely placed content inside them (such as a Select's hidden native control) stays in the pane instead of stretching the page.
-
PromptInput and Chat:
hint(PromptInput) andcomposerHint(Chat) replace the "Shift + Enter for a new line" line under the composer, for other languages or wording. -
Times: observed times (such as an approval's expiry or a timeline event) show in the viewer's time zone and locale once the page runs, with UTC in the tooltip. The server and the first render still show UTC, so both produce the same text.
-
Styling: disabled filled buttons (primary, danger) turn neutral grey instead of a faded copy of themselves, other disabled controls fade to 50%, placeholders are lighter than typed text, and the search field's clear button uses the theme's grey.
-
Tabs:
classNameon the root, for sizing tabs in your layout (for example a fixed height in a settings dialog). -
PromptInput: the message box grows with its text up to its maximum height, then scrolls, so multi-line messages and quotes stay in view.
-
AI SDK mapping: once the chat is idle, a tool call still receiving input or running reads as
cancelled, so a reply stopped mid-tool no longer shows a stuck "receiving input" card. -
MessageActions: thumbs icons, filled once rated, so the chosen rating is visible; the confirmation reads "Feedback sent." A person's own sent message no longer carries a "Response complete" status.
-
RunBoard:
hrefFormakes each card title a link, so runs open in a new tab with Ctrl or Cmd; a plain click still callsonSelect. -
RunBoard:
hideLabelkeeps the board's name for screen readers only, for pages whose tabs or heading already say which list it is. -
IconButton:
iconalso takes your own icon component, such as one from@radix-ui/react-icons, with the same size, tooltip and required label as the built-in names. -
PromptInput: after a "/" command the caret goes to the end of the message, so words the host puts in front ("Create an image of ") come before what you type next.
-
Video (
/media): new. A generated video with the same states as Image:queued,loadingwith host-measuredprogressand a softenedpreviewframe,failedwitherrorandonRetry, and a player with native controls once ready. It never autoplays, needs alabel, and refuses sources other than http(s) and blob:. -
Group chats: messages take an optional
author({ id, name, you? }), and the AI SDK mapping reads it from a user message'smetadata.author. Someone else's message is labelled with their name ("Message from Ben") and carriesdata-author="other"for your styling; yours still reads as You. -
ThreadList:
searchable={false}leaves out the search box, for a sidebar that searches in a dialog of its own. The compact variant's title now matches its date group labels. -
WorkspaceShell: a class that sets the shell's height, such as
height: 100dvh, now takes effect with the default pane scrolling, so navigation footers stay in view. -
MarkdownResponse:
citationsturns[1]-style markers in the text into citations that open their source. Markers inside code, and numbers without a source, stay as written. -
Image: generation states:
queued,loadingwith host-measuredprogressand a softened partialpreview, andfailedwitherrorandonRetry. Progress shows only when the host measured it. -
Tabs:
orientation="vertical"lists tabs beside the panel, as settings dialogs do, with up and down arrow keys; it stacks in narrow containers. -
ChatLauncher (
/chat): new. A floating chat bubble for websites that opens a non-modal chat panel (full screen on phones), focuses the composer, keeps the conversation mounted while closed, shows unread replies and returns focus to the bubble. -
SuggestTextarea (
/assistant): new. AI completion as ghost text after the caret; Tab accepts and Escape dismisses only while a suggestion shows, and screen readers hear it as a description. The host supplies suggestions. -
FileExplorer: files take optional
lines: { added, removed }, shown as a DiffStat beside the change badge, so the list view doubles as a changed-files list. -
ThreadList:
actionsputs controls such as New chat beside the title;groupBy="date"groups threads into Pinned, Today, Yesterday, Previous 7 days, Previous 30 days and Earlier from the new optionalupdatedAtandpinnedfields onThreadSummary(passnowso server and browser agree);rowActionsadds your own per-thread controls.groupThreadsByDateis exported. The compact variant is now a sidebar list: one line per thread with long titles cut short, no card backgrounds, and actions that appear on hover or keyboard focus (always on touch), staying put while their menu is open. -
RunBoard:
renderCardTrailingadds content at the end of each card's title row, such as a DiffStat, so the list variant works as a coding-agent task list. -
WorkSummary (
/assistant): new. The steps of one agent turn, open while it works and collapsed to "Worked for 15s" once done ("Stopped after", "Failed after"), with room for a log underneath. -
DiffStat: new. "+15 −1" for a change, with an optional file count and proportion blocks, read as "15 lines added, 1 removed".
-
ElapsedTime: new. Time spent on a run or turn ("2m 05s"), ticking while it runs and fixed once it ends, without interrupting screen readers.
formatElapsedis exported too. -
Checkbox, Switch, RadioGroup:
label(anddescriptionfor Checkbox and Switch) label the control without a separate Field. Checkbox and Switch render their own horizontal Field; RadioGroup renders the label as its legend. Keep using Field when you need an error message. -
Icons:
more,attach,sidebar,globe,newChatand a realmicrophoneglyph for IconButton. -
ToggleGroup: an option's
descriptionis now announced as a description, so the button's name stays "Search" rather than "Search Search the web". -
AI SDK approvals: the card is titled with the tool row's label (from
describeTool), its wording changes once you approve or reject, and the summary line shows only what is known. Unassessed risk and missing scopes are stated under Details instead. -
Types:
Step,MessageData,ToolCallData,ApprovalProposal,Source,Measurementand the other data shapes that props use now export from@stackunseen/ui, so apps need only that package. -
EmptyState: takes
title,description,iconandactionsdirectly; the composed parts still work. -
SplitPane: a responsive pane that stacks on a narrow screen now shows both panels at their natural height instead of collapsing to nothing.
-
Quieter output: TerminalOutput no longer reports a missing session for a plain log or offers "Pause following" after the process ends; CodeDiff says "New file" or "Deleted" and skips the newline note for them; compact AgentSteps keeps progress in the marker instead of repeating a badge on every step; a low-risk approval no longer shows a warning icon.
-
Component manifest:
@stackunseen/ui/manifest.jsonlists every export of every entry, each component's own props (with overloads merged), the naming rules and every--ai-*CSS variable, generated from the published types. Coding agents and tools can read the API from it instead of guessing. -
Design tokens: a new Design tokens page says what each
--ai-*variable is for, with its light and dark values. Component pages gain "Good to know" notes on deliberate behaviour and an "All props" table. -
Status in words: MCPServerCard, MCPToolList, FileExplorer, EvidenceGroup, ContextBar, MemoryControls, AgentHandoff, Commit, PackageInfo, ReviewChanges, TestResults, TerminalOutput, RunInspector, RunCompare, ApprovalCard and the mention picker show states as words;
auth-requiredreads "Sign-in required". -
Less repetition: BackgroundStatus hides zero counts ("Nothing running" when idle); MessageQueue tags only rows that are not plainly queued; AgentSteps drops the badge on finished steps; ScopeGrant no longer repeats "Expired" beside its badge and says "Uses not counted" with the reason; Attachment shows "CSV · 24.0 KiB" instead of "text/csv" and announces Ready without showing it; CodeTabs with
copyshows one copy button; ApprovalBatch, DryRunPreview and ScopeGrant meta lines are split by middle dots. -
ModelSelector: each model on a row with its description and a check beside the current one, instead of radio circles; the menu opens aligned to its button.
-
Layout: ArtifactDiff puts the two versions side by side; RunCompare row names align to the start; CodeDiff rows run to both edges of the card; the chat message action row sits right under the reply.
-
Sidebars: compact ThreadList actions are never taller than their row, so hovering never moves the list.
--ai-list-insetlines rows up with a host's navigation and--ai-navigation-gutter: autodrops the list's own scrollbar room when it grows inside another scroller. -
CodeDiff:
annotateplaces notes under a line, spanning both columns in the split view. Changed lines keep code in the text colour; the tint and the + or − marker show the change. -
RunBoard: list rows sit on two lines, with times in the viewer's time zone.
-
Select: ignores the empty value a form's hidden native select reports, so a choice no longer resets to the placeholder.
-
FileExplorer: shows only the metadata the host supplied, as plain rows with dividers.
-
Text: dialogs are centred without transforms, so their text stays sharp; the default font stack uses Segoe UI Variable on Windows 11. Set
--ai-font-familyto use a web font you load. -
Radio options are at least 24px tall with a mouse, so options without a description space like the rest.
-
Stylesheets:
styles/core.cssplus one sheet per base entry (styles/layout.css,styles/markdown.cssand so on) load less thanstyles.css, which is unchanged. Button always carriesdata-buttonfor styling. -
CodeDiff:
showVersions={false}hides the "base → next" line in the header, for pages that show several diffs of the same pair and state the comparison once. The versions still bind copies and feedback. -
Touch screens: hover styling applies only on devices that can hover, so a tap no longer leaves a button or row looking hovered. Inputs, textareas and the PromptInput box use 16px text on touch screens, so iOS Safari no longer zooms the page when they gain focus.
-
ClarificationRequest: an empty text answer reads "Enter an answer to continue.", matching "Choose an answer to continue." for choices.
-
Overlay motion: Modal and AlertDialog rise in with a light blur, Popover, Tooltip, DropdownMenu, ContextMenu and Select grow from the edge nearest their trigger, and backdrops fade. Each exit is shorter than its enter, and with reduced motion only opacity changes.
-
AppearanceToggle:
variant="switch", a sun and moon pill with only light and dark, andvariant="subtle", one quiet icon that cross-fades between them. Both start from the system's choice while the value issystem. The dark-mode glyph is now a plain crescent. -
TableOfContents:
variant="track"lists every level on a line that steps in with each level and darkens for the sections on screen, ending in a dot.variant="ticks"is a slim rail of marks for long reads, the current section longest, that opens into the titles on hover, focus or a press. -
Dashboard figures: new Sparkline (a word-sized trend for a stat or a table cell), BarList (ranked rows with a bar behind each printed value), Tracker (one block per day or run, coloured by status and named in a tooltip) and DonutChart (shares of one total, with the total in the centre and a legend that prints each share).
-
Dot figures: new DotRing, DotBars, WeekStrip and HeatKeys for counts drawn as dots or shaded cells. Every figure keeps its values in a hidden table and never relies on colour alone.
-
Numeric: new. A figure in tabular digits with its qualifier in words; Stat, ElapsedTime and ToolCall durations share its style, so numbers line up. Stat gains
variant="inset"for small figures inside a card, and Card gainsiconandCard.Section. -
Agent runs (
/conversation-flow): new AgentLanes (a lane per agent on one time axis, with hand-offs between lanes), AgentSteering (queue a note for a running agent's next step, bound to the run version it was written against), and CostLedger (cost per run that never adds measured and estimated figures together). SubagentTree takes a per-runcostand adds up each branch;branchCostis exported. RunBoard cards takestepsandmodel. -
ExecutionTimeline: steps take
cost,tokensandparentId, and the waterfall folds children under their parent on one shared axis. -
Assistant: new MemoryPanel (what the assistant remembers, where each memory came from and whether it was used; pin and forget are requests the host confirms), FollowUps (next-step chips after a reply), ContextWindowMeter (what fills the context window, from host numbers, marked when estimated) and TonePad (two settings on one square, built from two native sliders).
-
Kbd: new. One key cap; put each key of a combination in its own Kbd.
-
PromptInput:
variablesoffers placeholders as chips that insert{{id}}at the caret,limitshows a character count and stops sending past it, andassistholds extra actions such as "Enhance prompt". -
StreamingResponse:
progressshows where a multi-step answer stands as your server reports it, with an optional Stop action. -
Marketing (
/marketing): MarketingIllustration (four line drawings in the theme's colours), MarketingReveal (content that fades in on first view and is readable from the start) and MarketingNumber (a figure that counts up once, with the final value in the HTML). All three respect reduced motion. -
Variants on the server:
componentVariantsandresolveVariantare exported from@stackunseen/ui/theme, which has no client directive.useThemeScopelets overlay content carry the theme without a wrapper. -
CodeEditor: code and line numbers use the theme's mono font, the gutter fills the editor's minimum height (
--ai-code-editor-min-height,--ai-code-editor-max-height), and only the editor draws a focus ring. -
Fixes: Chart draws at its container's width and scrolls only when the data needs more room; CostLedger keeps the total's figure in the Cost column; ModelSelector's menu padding reaches the popover body; CommandPalette shows search focus as an underline; TestResults rows line up with the header; Snippet wraps long commands instead of scrolling.
0.1.0-alpha.10 — 20 October 2026
- Previews: small components (Breadcrumb, Pagination, Stepper, ModelSelector, Persona, badges and others) sit centred in the component pages instead of in the top-left corner, and expandable rows (ToolCall, ToolGroup, Sources, ChainOfThought) use a centred column so opening them doesn't shift the layout.
- Plan: finished steps show their tick again.
- Narrow screens: StatusBadge and RunCompare keep words like "Succeeded" whole instead of splitting them; Checkpoint wraps its date as one line of text; MCPAppFrame moves its status and Close under the title rather than squeezing it.
0.1.0-alpha.9 — 19 October 2026
- Docs: rewritten package READMEs, a contributing guide and a security policy.
0.1.0-alpha.8 — 19 October 2026
- Chat: a new
@stackunseen/ui/chatentry withChat, a complete chat surface, anduseLocalHostfor prototypes. - AI SDK:
useAiSdkChat(useChat())connects Chat to the Vercel AI SDK, with tool approvals shown as approval cards.@stackunseen/ui-core/ai-sdkhas the mapping for custom layouts. - Shorter inputs: Message accepts
{ role, text }; ToolCall and ToolGroup accept{ name }plus what you know. - Compact by default: ToolCall, ToolGroup, RunInspector, WorkflowGraph and ExecutionTimeline take
detail: 'compact' | 'full'and hide revisions, durations and source lines unless asked. - Honest approvals: ApprovalCard reads "Risk not assessed" and "None supplied" instead of invented values when the host has none.
- Quieter defaults: the default primary is neutral ink (
#171717; passprimaryfor a brand colour), corners are 12px on panels and 10px on controls, and dark-mode field borders are softer while staying above 3:1. - Tool rows: ToolCall
variant="row"and ToolGroupvariant="list"show one line per step with a host-writtenlabel,targetand duration; messages and Chat use rows. The AI SDK mapping takesdescribeToolfor those words. - Composer: a round send button, the keyboard hint only while typing, and ModelSelector
variant="ghost"for toolbars. - Decisions: a decided ApprovalCard shows its outcome instead of disabled buttons; Combobox shows the chosen value in the field with an inline clear; ChainOfThought ticks finished steps and spins the active one.
- shadcn registry:
npx shadcn@latest add https://unseenui.com/r/chat.json(or@unseen/chatwith the namespace incomponents.json) installs@stackunseen/uiat the release and writes a starter. Items:chat,chat-ai-sdk(withapp/api/chat/route.ts) andtheme. They matchnpx @stackunseen/ui init. - More merges: Workflow is
AgentSteps dependencies(withselectedId/onSelect); MultiSelect isCombobox type="multiple"; ReasoningControl is removed (useToggleGroup variant="segmented"orSelect); OpenInChat is ShareMenu targets (custom targets now accept only http(s), mailto or relative links); Task is ChainOfThought (steps take afailedstate, files are sources); LinkButton isButton href; Chip has no static form (use Tag); Shimmer and DataTable are internal (use DataGrid for application tables). - Merged components: SegmentedControl is now
ToggleGroup variant="segmented"(withmode="links"and optiondescription); Chip keeps its link, removable and static forms, and choices move to ToggleGroup; LinkCard isCard href(withexternal); Panel and PanelHeader fold into Card, whoseCard.Headertakesactions. - Fewer, broader components: Disclosure is removed (use Accordion with one item), ProgressRing is now
Progress variant="ring", and Kbd, SkipLink and VisuallyHidden are no longer exported (use a<kbd>, an anchor and your own screen-reader class). Stat draws each figure as its own card;variant="plain"keeps the bare figure. - Button:
variant="link"for text-like actions; DataGridcaptionVisibility="hidden"for tables inside titled cards. - Site: gallery and list views with live-preview thumbnails, search by meaning, task pages, Patterns in the navigation, an AI SDK recipe, this changelog, and
llms.txtfor coding agents.
0.1.0-alpha.7 — 16 October 2026 (published 19 October 2026)
- Runs: RunBoard, AttentionQueue, RunSummaryCard, BackgroundStatus, RunCompare and SubagentTree in
/conversation-flow. - Generated interfaces: a streaming line format and parser for GeneratedUI, prompt text from the vocabulary, A2UI v1.0 mapping, and new nodes (list, callout, options, steps, image, metric group).
- MCP Apps: MCPAppFrame in a new
/mcp-appsentry with a sandboxed bridge; a ToolResult renderer registry and partial results. - Approvals: ScopeGrant, DryRunPreview and ApprovalBatch, plus AG-UI interrupt and MCP elicitation adapters.
- Trust signals: UsageMeter, ProvenanceBadge, ConfidenceNote and FeedbackCapture.
- Design language: zinc neutrals, motion and type tokens, readable soft colour pairs.
- Docs: install and import on every component page, tasks for discovery, related components, copy buttons on code blocks.
- Fixes: Matrix plain data, FilterBar search row, Stepper segments, CodeTabs reveal, contrast, ModelSelector mark, row spacing, FileDropzone.
0.1.0-alpha.6 — 14 October 2026
- Fourteen follow-ups from adopting alpha.5 on the StackUnseen site.
0.1.0-alpha.5 — 13 October 2026
- Site components: CommandPalette, TableOfContents, ShareMenu, CopyButton, InputGroup, AppearanceToggle, ProgressRing, Checklist and CodeTabs, with documentation and showcases.
0.1.0-alpha.4 — 9 October 2026
- Router links for linked controls, link-mode tab order, Stepper tooltips, Matrix headers and fills, the Sidecar sheet and the FilterBar pattern.
0.1.0-alpha.1 to alpha.3 — 7 to 9 October 2026
- The first public prereleases of the component set, the theme and the docs site.