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.
/r/registry.json, so an agent can list the registry with no server running.{ 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 filescurl http://127.0.0.1:3000/api/registry/chat# Search the same corpus the ⌘K palette usescurl "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.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 } enveloperefined-ui list # every itemrefined-ui search chat # ranked matchesrefined-ui get chat --json # one item, envelope verbatimrefined-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 listAgent 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 registrybun 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.txtGap 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 shortrefined-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