|
|
2 月之前 | |
|---|---|---|
| .. | ||
| app | 2 月之前 | |
| lib | 2 月之前 | |
| .env.example | 2 月之前 | |
| README.md | 2 月之前 | |
| eslint.config.js | 2 月之前 | |
| next.config.ts | 2 月之前 | |
| package.json | 2 月之前 | |
| tsconfig.json | 2 月之前 | |
An AI-powered chat where each assistant reply streams a fresh Spec that renders inline. A single <JsonRenderDevtools /> panel observes every rendered spec, every streamed patch, every state change, and every dispatched action across the whole page — demonstrating how one devtools instance works with many renderers.
Pairs with @json-render/devtools and @json-render/devtools-react.
specfence of RFC 6902 JSON patches.pipeJsonRenderon the server splits that intodata-specparts and plain text parts; the client re-assembles both withuseJsonRenderMessage`.<Renderer />, but they share a single top-level <JSONUIProvider>, so the devtools State / Actions / Stream tabs see the whole page, not just one message.messageId and requires every element key (<id>-root, <id>-counter, …) and state path (/<id>/count, /<id>/todos) to be prefixed with it, so specs from different messages never collide on shared state.setState, pushState, removeState, plus inc/dec/toggle/add computed functions, $bindState, $template, $state, repeat, $item, $index, and conditional visible.data-jr-key, picking an element in any assistant bubble jumps to its spec in the panel.pnpm install
cp .env.example .env.local
# Edit .env.local and set AI_GATEWAY_API_KEY
Grab an AI Gateway key at https://vercel.com/ai-gateway. On Vercel the key is auto-authenticated, so you only need this for local dev.
pnpm dev
# http://devtools-demo.json-render.localhost:1355
Press ⌘ ⇧ J (or click the floating {} badge) to toggle the panel. It starts open by default.
app/page.tsx — chat UI, top-level <JSONUIProvider>, per-message <Renderer />, <JsonRenderDevtools> mountapp/api/chat/route.ts — streams the agent through pipeJsonRenderlib/agent.ts — ToolLoopAgent with a system prompt that enforces inline mode + messageId-based namespacinglib/catalog.ts — compact catalog (Card, Stack, Grid, Metric, Button, TextInput, Checkbox, List, ProgressBar, Callout, …) tuned to show off devtoolslib/registry.tsx — component renderers with plain inline styles, no UI frameworksetState dispatches.pushState / removeState and $bindState inputs.Then send a second prompt in the same session and watch the Stream tab keep appending patches while the State tab shows both turns' namespaced keys side by side.