Instructions for AI coding agents working with this codebase.
Always check the latest version before installing a package.
Before adding or updating any dependency, verify the current latest version on npm:
npm view <package-name> version
Or check multiple packages at once:
npm view ai version
npm view @ai-sdk/provider-utils version
npm view zod version
This ensures we don't install outdated versions that may have incompatible types or missing features.
pnpm dlx shadcn@latest add <component>apps/web/): Never use Markdown table syntax (| col | col |). Always use HTML <table> with <thead>, <tbody>, <tr>, <th>, <td>. Markdown tables do not render correctly in the web app. Inside HTML table cells, curly braces must be escaped as JSX expressions (e.g. <code>{'{ "$state": "/path" }'}</code>) because MDX parses { as a JSX expression boundary.When using the Vercel AI SDK (ai package) with AI Gateway, pass the model as a plain string identifier -- do not import a provider constructor:
import { streamText } from "ai";
const result = streamText({
model: "anthropic/claude-haiku-4.5",
prompt: "...",
});
This requires AI_GATEWAY_API_KEY to be set in the environment. See tests/e2e/ for examples.
All apps and examples with dev servers use portless to avoid hardcoded ports. Portless assigns random ports and exposes each app via .localhost URLs.
Naming convention:
json-render → json-render.localhost:1355[name]-demo.json-render → [name]-demo.json-render.localhost:1355When adding a new example that runs a dev server, wrap its dev script with portless <name>:
{
"scripts": {
"dev": "portless my-example-demo.json-render next dev --turbopack"
}
}
Do not add --port flags -- portless handles port assignment automatically. Do not add portless as a project dependency; it must be installed globally.
pnpm type-check after each turn to ensure type safetyREADME.md files in packages/*/README.mdREADME.md (if packages table, install commands, or examples are affected)apps/web/ (if guides, API references, or examples need updating)skills/*/SKILL.md (if the package has a corresponding skill)AGENTS.md (if workflow or conventions change)Releases are manual, single-PR affairs. The maintainer controls the changelog voice and format.
All public @json-render/* packages share the same version. The canonical version lives in packages/core/package.json.
When asked to prepare a release (e.g. "prepare v0.17.0"):
prepare-v0.17.0)packages/core/package.jsonpnpm run version:sync to update all other @json-render/* packagesCHANGELOG.md, wrapped in <!-- release:start --> and <!-- release:end --> markers (move the markers from the previous entry to the new one)README.md packages tableREADME.md (if it's a renderer)apps/web/app/(main)/docs/api/<name>/page.mdxapps/web/lib/page-titles.ts and apps/web/lib/docs-navigation.tsapps/web/app/api/docs-chat/route.ts)skills/<name>/SKILL.mdpackages/<name>/README.mdpnpm type-check after all changes to verify nothing is brokenmainCI compares the @json-render/core version to what's on npm. If it differs, it builds, publishes all public packages, and creates the GitHub release automatically. The release body is extracted from the content between the markers.
pnpm run version:sync — sync all @json-render/* package versions to match @json-render/corepnpm run version:check — verify all versions are in sync (runs in CI)pnpm run ci:publish — build all packages and publish to npm (CI only)Source code for dependencies is available in opensrc/ for deeper understanding of implementation details.
See opensrc/sources.json for the list of available packages and their versions.
Use this source code when you need to understand how a package works internally, not just its types/interface.
To fetch source code for a package or repository you need to understand, run:
npx opensrc <package> # npm package (e.g., npx opensrc zod)
npx opensrc pypi:<package> # Python package (e.g., npx opensrc pypi:requests)
npx opensrc crates:<package> # Rust crate (e.g., npx opensrc crates:serde)
npx opensrc <owner>/<repo> # GitHub repo (e.g., npx opensrc vercel/ai)