Refined UI

An opinionated, customizable superset of shadcn/ui

AgentsPrimitivesSkillsSkins
Guides
  • Overview
  • Get started
  • Shadcn compatibility
  • Architecture
  • Agent surface
Agents
  • Action Bar
  • Audio Recorder
  • Audio VisualizerBetaBeta — the props contract is close to final, but small breaking changes can still land.
  • Chat Input
  • Chat Input Attachment
  • Chat Message
  • Chat Scene
  • Code Block Editor
  • Dynamic NotificationExpExperimental — the contract and the rendering can change without notice. Own the installed copy before shipping it.
  • Environment Variables
  • Inline Attachment
  • Markdown Block
  • Task List
  • Thread Rail
  • Tool Call
  • User Ask
Blocks
  • Chat
  • Theme toggle
  1. Guides
  2. Agent surface
Guide

Agent surface

This is an agent UI registry, so it exposes an agent-readable surface: an HTTP API, a CLI, and an injected AGENTS.md / llms.txt cheat-sheet — all generated from one serializer over the same catalog these docs render.

One serializer, one envelope

Every machine surface - the HTTP routes, the CLI, the static index, and the injected agent docs - is generated from a single server module over the same catalog and on-disk sources the human pages render. Every response is the { type, data } envelope, and errors carry a stable code.

The search corpus is shared with the command palette, so human search and agent search rank the exact same items.
Reads are prerendered at build and also dumped to /r/registry.json, so an agent can list the registry with no server running.
A miss returns { error, code: "ERR_UNKNOWN_ITEM", suggestions }, with suggestions from a small id similarity check.

HTTP API

Three GET routes live under /api/registry. The index lists every item with its install command; the item route adds parsed dependencies and readable source files; search ranks the shared corpus by query.

# List every registry item (id, kind, summary, install command)
curl http://127.0.0.1:3000/api/registry
​
# Read one item — install commands, parsed deps, readable source files
curl http://127.0.0.1:3000/api/registry/chat
​
# Search the same corpus the ⌘K palette uses
curl "http://127.0.0.1:3000/api/registry/search?q=chat"
​
# Every response is the same envelope:
# { "type": "item", "data": { … } }
# A miss is a 404 carrying a stable code:
# { "error": "…", "code": "ERR_UNKNOWN_ITEM", "suggestions": [ … ] }

CLI

@refined-ui/cli wraps those routes over HTTP against REFINED_UI_REGISTRY_URL, so the same commands work against local dev and any deploy. Pass --json to print the envelope verbatim; without it you get a human table. add stays on the authoritative shadcn path.

list, search, get, and add - every read command accepts --json for the raw { type, data } envelope.
add <id> shells npx shadcn@latest add <manifestUrl>, never a second install path.
A miss prints the ERR_UNKNOWN_ITEM suggestions as a Did you mean: list and exits non-zero.
# Every read command takes --json to print the raw { type, data } envelope
refined-ui list # every item
refined-ui search chat # ranked matches
refined-ui get chat --json # one item, envelope verbatim
refined-ui add chat # runs `npx shadcn@latest add …`
​
# Point the CLI at any deploy (defaults to local dev):
REFINED_UI_REGISTRY_URL=https://your-registry.app refined-ui list

Agent docs - AGENTS.md & llms.txt

A generator turns the registry into a dense cheat-sheet: the item list plus the @refined-ui/skills practice rules and the install/skin workflow. It injects between markers in AGENTS.md and writes public/llms.txt for zero-tooling agents.

# Regenerate the agent cheat-sheet + llms.txt from the registry
bun run docs:agents
​
# Injected between markers in AGENTS.md (and CLAUDE.md if present):
<!-- REFINED-UI:START -->
… dense item list + @refined-ui/skills practice rules + workflow …
<!-- REFINED-UI:END -->
​
# Zero-tooling agents read the same content at:
http://127.0.0.1:3000/llms.txt

Gap feedback

Ejecting is just shadcn add - but when an ejected component falls short, --gap captures why as a signal instead of losing it. It posts to /api/gaps, appends to .gaps/gaps.jsonl, and GET aggregates the log for a future roadmap view.

# Eject a component AND log why it fell short
refined-ui add chat --gap "needed streaming markdown"
​
# POSTs to /api/gaps → appended to .gaps/gaps.jsonl (gitignored):
{"item":"chat","reason":"needed streaming markdown","ts":"…"}
​
# Read the aggregated log for a roadmap view:
curl http://127.0.0.1:3000/api/gaps

On this page

  • One serializer, one envelope
  • HTTP API
  • CLI
  • Agent docs — AGENTS.md & llms.txt
  • Gap feedback