diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 98f0ce5f..53b7ecb3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -87,7 +87,34 @@ jobs: run: pnpm run build - name: Publish all public packages - run: pnpm -r publish --provenance --no-git-checks --access public --filter '@json-render/*' + run: | + LOCAL_VERSION="${{ needs.check-release.outputs.version }}" + FAILED="" + + publish_pkg() { + local dir="$1" name="$2" + REGISTRY_VERSION=$(npm view "$name" version 2>/dev/null || echo "0.0.0") + if [ "$LOCAL_VERSION" = "$REGISTRY_VERSION" ]; then + echo "$name@$LOCAL_VERSION already published, skipping" + return 0 + fi + echo "Publishing $name@$LOCAL_VERSION..." + TARBALL=$(cd "$dir" && pnpm pack --pack-destination /tmp | tail -1) + if ! npm publish "$TARBALL" --provenance --access public; then + FAILED="$FAILED $name" + fi + } + + for dir in packages/*/; do + PKG_NAME=$(node -p "try { const p = require('./$dir/package.json'); p.private ? '' : p.name } catch { '' }") + [ -z "$PKG_NAME" ] && continue + publish_pkg "$dir" "$PKG_NAME" + done + + if [ -n "$FAILED" ]; then + echo "Failed to publish:$FAILED" + exit 1 + fi github-release: name: Create GitHub Release diff --git a/CHANGELOG.md b/CHANGELOG.md index 880263d4..6cc8c37a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,26 @@ # Changelog -## 0.18.0 +## 0.19.0 ### New Features +- **Custom directives API** — `@json-render/core` now supports custom directives via `defineDirective`, letting you declare new JSON shapes (like `$format`, `$math`) that resolve to computed values at render time. Directives compose naturally — nest `$format` over `$math` over `$state` and they resolve inside-out. All four renderers (React, Vue, Svelte, Solid) have built-in directive resolution (#279) +- **`@json-render/directives`** — New package shipping seven ready-made directives: `$format` (date, currency, number, percent via `Intl`), `$math` (add, subtract, multiply, divide, mod, min, max, round, floor, ceil, abs), `$concat`, `$count`, `$truncate`, `$pluralize`, and `$join`. Also exports `createI18nDirective` for `$t` translation keys with `{{param}}` interpolation, and `standardDirectives` for one-line registration (#279) + +### Improvements + +- **Example READMEs** — Added documentation to the chat, dashboard, game-engine, and no-ai examples (#277) + +### Contributors + +- @ctate + + +## 0.18.0 + +### New Features + - **Devtools** — Five new packages for inspecting json-render apps in the browser: `@json-render/devtools` (framework-agnostic core), plus `@json-render/devtools-react`, `@json-render/devtools-vue`, `@json-render/devtools-svelte`, and `@json-render/devtools-solid` adapters. Drop `` into your app to get a shadow-DOM-isolated panel with six tabs (Spec, State, Actions, Stream, Catalog, Pick), a DOM picker that maps clicked elements back to spec keys via `data-jr-key`, a capped event store, and server-side stream tap utilities. Floating toggle or `Cmd`/`Ctrl` + `Shift` + `J`, tree-shakes to `null` in production (#273) - **Devtools example** — New `examples/devtools` Next.js demo showing the full devtools panel wired up to an AI chat endpoint and a component catalog (#273) - **Action observer and devtools flag in core** — `@json-render/core` now exposes an action observer and a devtools enablement flag that adapters use to mirror actions and stream events into the panel (#273) @@ -21,7 +37,6 @@ - @ctate - @mvanhorn - ## 0.17.0 diff --git a/apps/web/app/(main)/docs/changelog/page.mdx b/apps/web/app/(main)/docs/changelog/page.mdx index da857b75..a5ca4e97 100644 --- a/apps/web/app/(main)/docs/changelog/page.mdx +++ b/apps/web/app/(main)/docs/changelog/page.mdx @@ -5,6 +5,35 @@ export const metadata = pageMetadata("docs/changelog") Notable changes and updates to json-render. +## v0.19.0 + +May 6, 2026 + +### New: Custom Directives API + +`@json-render/core` now supports custom directives via `defineDirective`, letting you declare new JSON shapes (like `$format`, `$math`) that resolve to computed values at render time. Directives compose naturally -- nest `$format` over `$math` over `$state` and they resolve inside-out. All four renderers (React, Vue, Svelte, Solid) have built-in directive resolution. + +### New: `@json-render/directives` + +New package shipping seven ready-made directives: `$format` (date, currency, number, percent via `Intl`), `$math` (arithmetic and rounding), `$concat`, `$count`, `$truncate`, `$pluralize`, and `$join`. Also exports `createI18nDirective` for `$t` translation keys with interpolation, and `standardDirectives` for one-line registration. + +```bash +npm install @json-render/directives +``` + +```tsx +import { standardDirectives } from "@json-render/directives"; + +const catalog = createCatalog({ + directives: standardDirectives, + // ... +}); +``` + +See the [Directives guide](/docs/directives) and the [API reference](/docs/api/directives) for details. + +--- + ## v0.18.0 April 17, 2026 diff --git a/packages/codegen/package.json b/packages/codegen/package.json index 637bc131..956c0404 100644 --- a/packages/codegen/package.json +++ b/packages/codegen/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/codegen", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Utilities for generating code from json-render UI trees", "keywords": [ diff --git a/packages/core/package.json b/packages/core/package.json index e7bbd48f..979338b7 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/core", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "JSON becomes real things. Define your catalog, register your components, let AI generate.", "keywords": [ diff --git a/packages/devtools-react/package.json b/packages/devtools-react/package.json index 11782654..a6e62dee 100644 --- a/packages/devtools-react/package.json +++ b/packages/devtools-react/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/devtools-react", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "React adapter for @json-render/devtools. Drop-in component.", "keywords": [ diff --git a/packages/devtools-solid/package.json b/packages/devtools-solid/package.json index d865f6d9..bcafb3df 100644 --- a/packages/devtools-solid/package.json +++ b/packages/devtools-solid/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/devtools-solid", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "SolidJS adapter for @json-render/devtools. Drop-in component.", "keywords": [ diff --git a/packages/devtools-svelte/package.json b/packages/devtools-svelte/package.json index 1a7118ec..176e7e87 100644 --- a/packages/devtools-svelte/package.json +++ b/packages/devtools-svelte/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/devtools-svelte", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Svelte adapter for @json-render/devtools. Drop-in component.", "keywords": [ diff --git a/packages/devtools-vue/package.json b/packages/devtools-vue/package.json index 1a16e1e9..7891db3f 100644 --- a/packages/devtools-vue/package.json +++ b/packages/devtools-vue/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/devtools-vue", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Vue adapter for @json-render/devtools. Drop-in component.", "keywords": [ diff --git a/packages/devtools/package.json b/packages/devtools/package.json index 201ad617..1d49952a 100644 --- a/packages/devtools/package.json +++ b/packages/devtools/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/devtools", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Framework-agnostic devtools core for json-render: event store, panel UI, picker, stream taps.", "keywords": [ diff --git a/packages/directives/package.json b/packages/directives/package.json index 86a97a75..db354dd9 100644 --- a/packages/directives/package.json +++ b/packages/directives/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/directives", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Pre-built directives for @json-render/core — $format, $math, $concat, $count, $truncate, $pluralize, $join, and $t (i18n).", "keywords": [ diff --git a/packages/image/package.json b/packages/image/package.json index c7a0b3dc..791bd21c 100644 --- a/packages/image/package.json +++ b/packages/image/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/image", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Image renderer for @json-render/core. JSON becomes SVG and PNG images via Satori.", "keywords": [ diff --git a/packages/ink/package.json b/packages/ink/package.json index 955f5d74..dfe465aa 100644 --- a/packages/ink/package.json +++ b/packages/ink/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/ink", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Ink terminal renderer for @json-render/core. JSON becomes terminal UIs.", "keywords": [ diff --git a/packages/jotai/package.json b/packages/jotai/package.json index 90094f84..b2c1828c 100644 --- a/packages/jotai/package.json +++ b/packages/jotai/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/jotai", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Jotai adapter for json-render StateStore", "keywords": [ diff --git a/packages/mcp/package.json b/packages/mcp/package.json index 06590931..0aef4cd3 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/mcp", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "MCP Apps integration for @json-render/core. Serve json-render UIs as interactive MCP Apps in Claude, ChatGPT, Cursor, and VS Code.", "keywords": [ diff --git a/packages/next/package.json b/packages/next/package.json index 2492602c..298bf89b 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/next", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Next.js renderer for @json-render/core. JSON becomes full Next.js applications with routes, layouts, metadata, and SSR.", "keywords": [ diff --git a/packages/react-email/package.json b/packages/react-email/package.json index c1bddd79..4f8355a8 100644 --- a/packages/react-email/package.json +++ b/packages/react-email/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/react-email", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "React Email renderer for @json-render/core. JSON becomes HTML emails.", "keywords": [ diff --git a/packages/react-native/package.json b/packages/react-native/package.json index f4e26d23..ffcb46ac 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/react-native", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "React Native renderer for @json-render/core. JSON becomes React Native components.", "keywords": [ diff --git a/packages/react-pdf/package.json b/packages/react-pdf/package.json index f0819d36..a9b0b5ce 100644 --- a/packages/react-pdf/package.json +++ b/packages/react-pdf/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/react-pdf", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "React PDF renderer for @json-render/core. JSON becomes PDF documents.", "keywords": [ diff --git a/packages/react-three-fiber/package.json b/packages/react-three-fiber/package.json index ecd05fd6..278aca0f 100644 --- a/packages/react-three-fiber/package.json +++ b/packages/react-three-fiber/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/react-three-fiber", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "React Three Fiber renderer for @json-render/core. JSON becomes 3D scenes.", "keywords": [ diff --git a/packages/react/package.json b/packages/react/package.json index 80870be5..d64678f2 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/react", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "React renderer for @json-render/core. JSON becomes React components.", "keywords": [ diff --git a/packages/redux/package.json b/packages/redux/package.json index 75d332b0..f27edf85 100644 --- a/packages/redux/package.json +++ b/packages/redux/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/redux", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Redux adapter for json-render StateStore", "keywords": [ diff --git a/packages/remotion/package.json b/packages/remotion/package.json index 5b28a5f7..85d9abf3 100644 --- a/packages/remotion/package.json +++ b/packages/remotion/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/remotion", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Remotion renderer for @json-render/core. JSON becomes video compositions.", "keywords": [ diff --git a/packages/shadcn-svelte/package.json b/packages/shadcn-svelte/package.json index 61ed693e..122718b2 100644 --- a/packages/shadcn-svelte/package.json +++ b/packages/shadcn-svelte/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/shadcn-svelte", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "shadcn-svelte component library for @json-render/svelte. JSON becomes beautiful Tailwind-styled Svelte components.", "keywords": [ diff --git a/packages/shadcn/package.json b/packages/shadcn/package.json index 78094dd7..18569b07 100644 --- a/packages/shadcn/package.json +++ b/packages/shadcn/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/shadcn", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "shadcn/ui component library for @json-render/core. JSON becomes beautiful Tailwind-styled React components.", "keywords": [ diff --git a/packages/solid/package.json b/packages/solid/package.json index e0edc025..12ebe16c 100644 --- a/packages/solid/package.json +++ b/packages/solid/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/solid", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "SolidJS renderer for @json-render/core. JSON becomes Solid components.", "keywords": [ diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 43529f69..c64549d7 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/svelte", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Svelte 5 renderer for @json-render/core. JSON becomes Svelte components.", "keywords": [ diff --git a/packages/vue/package.json b/packages/vue/package.json index 59773146..608741a1 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/vue", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Vue renderer for @json-render/core. JSON becomes Vue components.", "keywords": [ diff --git a/packages/xstate/package.json b/packages/xstate/package.json index 33f233b5..8e5e631c 100644 --- a/packages/xstate/package.json +++ b/packages/xstate/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/xstate", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "XState Store adapter for json-render StateStore", "keywords": [ diff --git a/packages/yaml/package.json b/packages/yaml/package.json index 45fe2a35..7fafb4eb 100644 --- a/packages/yaml/package.json +++ b/packages/yaml/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/yaml", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "YAML wire format for @json-render/core. Progressive rendering and surgical edits via streaming YAML.", "keywords": [ diff --git a/packages/zustand/package.json b/packages/zustand/package.json index 49d5cab1..bf33f826 100644 --- a/packages/zustand/package.json +++ b/packages/zustand/package.json @@ -1,6 +1,6 @@ { "name": "@json-render/zustand", - "version": "0.18.0", + "version": "0.19.0", "license": "Apache-2.0", "description": "Zustand adapter for json-render StateStore", "keywords": [