@nexart/ui-renderer 0.8.8 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,403 +1,371 @@
1
1
  # @nexart/ui-renderer
2
2
 
3
- Version: 0.8.7
3
+ **Version: 0.9.1**
4
4
 
5
- **Lightweight Preview Runtime for NexArt Protocol**
5
+ A browser-first bounded generative renderer for safe, fast, interactive visuals.
6
6
 
7
7
  ---
8
8
 
9
- > **This SDK is a PREVIEW RENDERER, not an authority.**
10
- >
11
- > It provides fast, lightweight previews for development and prototyping.
12
- >
13
- > It is:
14
- > - **NOT canonical** — Does not produce archival-quality output
15
- > - **NOT archival** — Not for minting, export, or permanent storage
16
- > - **NOT protocol-enforcing** — No validation errors, no pattern checking
17
- >
18
- > For canonical output, minting, or validation: use `@nexart/codemode-sdk`
9
+ ## What This SDK Does
19
10
 
20
- ---
11
+ This SDK provides a **bounded execution environment** for running generative code safely in the browser. It renders p5-like sketches with built-in safety limits:
21
12
 
22
- ## v0.8.7Live Runtime Binding Fix
23
-
24
- Fixed critical bug where time-varying properties were frozen in loop mode.
25
-
26
- - **Live binding**: `frameCount`, `t`, `time`, `tGlobal`, `totalFrames` now update every frame
27
- - **Proxy + with pattern**: Uses a Proxy scope with `with()` for live property access
28
- - **Animations work**: Sketches see correct values on every frame
29
-
30
- **Animation Semantics:**
31
- In loop mode, all time variables update every frame:
32
- - `frameCount`: Increments each frame
33
- - `t`: Normalized time `(frameCount % totalFrames) / totalFrames` (range [0,1))
34
- - `time`: Alias for `t`
35
- - `tGlobal`: Alias for `t`
36
- - `totalFrames`: Total frames in the loop (default 120)
37
-
38
- **Test Sketch:**
39
- ```javascript
40
- function draw() {
41
- background(0);
42
- fill(255);
43
- circle(
44
- width / 2 + sin(frameCount * 0.1) * 300,
45
- height / 2,
46
- 120
47
- );
48
- }
49
- ```
50
- Expected: Circle moves horizontally, motion is continuous.
13
+ - **Resolution cap** Max 900px dimension for performance
14
+ - **Frame/time budgets** — Prevents runaway loops
15
+ - **Observable state** Know exactly what the runtime is doing
16
+ - **Safe degradation** — Controlled behavior when limits hit
17
+
18
+ **Output is authoritative within bounded constraints.** What you see is what the sketch produces at preview resolution with preview budgets.
51
19
 
52
20
  ---
53
21
 
54
- ## v0.8.3 Animation Loop Fix
22
+ ## Standalone Use Cases
55
23
 
56
- Fixed critical bug where preview only rendered a single frame.
24
+ This SDK is designed for:
57
25
 
58
- - **RAF unconditionally scheduled**: `requestAnimationFrame(loop)` is now called on every tick
59
- - **Budget gates draw only**: Frame budget controls whether `draw()` runs, not whether the loop continues
60
- - **Continuous animation**: Loop runs forever until explicitly stopped
26
+ - **Generative art backgrounds** Dynamic visuals for web pages
27
+ - **Interactive creative coding editors** Live preview while users code
28
+ - **Dashboard visuals** Procedural data visualizations
29
+ - **Mini-app visuals** — Embedded generative elements
30
+ - **Educational demos** — Safe sandbox for teaching creative coding
31
+ - **UI-embedded procedural patterns** — Decorative generative elements
61
32
 
62
- **Animation Loop Invariant (locked for v0.x):**
63
- ```
64
- RAF schedules → budget checks → draw executes (or skips) → repeat
65
- Never: budget check → stop loop
66
- ```
33
+ For these use cases, ui-renderer is the complete solution. No other SDK required.
67
34
 
68
35
  ---
69
36
 
70
- ## v0.8.2 Runtime Dimensions Fix
37
+ ## When to Escalate to Canonical Rendering
71
38
 
72
- Fixed critical bug where preview scaling affected `width`/`height` inside sketches.
39
+ Use `@nexart/codemode-sdk` when you need:
73
40
 
74
- - **Runtime uses original dimensions**: `width` and `height` now match Code Mode exactly
75
- - **Canvas buffer still scaled for performance**: Rendering is fast, semantics are correct
76
- - **Loop animations work correctly**: Geometry math and timing no longer break
41
+ - **Minting / export / archival** Permanent, verifiable output
42
+ - **Reproducibility guarantees** Exact same output every time, anywhere
43
+ - **Full resolution parity** 1950×2400 or higher without scaling
44
+ - **Verification workflows** — Cryptographic digest matching
77
45
 
78
- **Key rule enforced:** Preview scaling is a rendering concern, not a semantic one.
46
+ **ui-renderer codemode-sdk is an escalation, not a requirement.**
79
47
 
80
- ---
48
+ Most interactive, preview, and display use cases are complete with ui-renderer alone.
81
49
 
82
- ## v0.8.1 — Canvas Scaling Fix
50
+ ---
83
51
 
84
- Fixed canvas zoom/cropping bug caused by resolution downscaling in v0.8.0.
52
+ ## Authority Model
85
53
 
86
- - **Scale Transform Reapplied**: Context scale is now properly restored after canvas resize
87
- - **Transform-Safe Clear**: `clearRect` now ignores active transforms for correct full-canvas clearing
88
- - **No API Changes**: All fixes are internal
54
+ ```
55
+ ┌─────────────────────────────────────────────────────────┐
56
+ │ Your Application │
57
+ │ (React, Canvas, Three.js, editor, dashboard) │
58
+ └────────────────────────┬────────────────────────────────┘
59
+
60
+
61
+ ┌─────────────────────────────────────────────────────────┐
62
+ │ @nexart/ui-renderer │
63
+ │ Bounded browser runtime │
64
+ │ - Resolution scaling (max 900px) │
65
+ │ - Frame/time budgets │
66
+ │ - Observable stats │
67
+ │ - Controlled degradation │
68
+ └────────────────────────┬────────────────────────────────┘
69
+
70
+
71
+ ┌─────────────────────────────────────────────────────────┐
72
+ │ Output │
73
+ │ - Pixels on canvas │
74
+ │ - Runtime stats │
75
+ │ - Budget status │
76
+ │ │
77
+ │ ↳ Optional: toCanonicalRequest() for codemode-sdk │
78
+ └─────────────────────────────────────────────────────────┘
79
+ ```
89
80
 
90
81
  ---
91
82
 
92
- ## v0.8.0 Lightweight Preview Runtime
83
+ ## For AI Coding Agents (Replit / Lovable / Claude Code)
93
84
 
94
- This release refactors the UI renderer into a performance-optimized preview runtime.
85
+ ### 20-Second Quickstart
95
86
 
96
- ### Philosophy Change
87
+ ```typescript
88
+ import { createPreviewRuntime } from '@nexart/ui-renderer';
97
89
 
98
- **The UI renderer is explicitly preview-only:**
99
- - No protocol errors thrown
100
- - No forbidden pattern checking
101
- - Soft warnings instead of hard failures
102
- - Permissive — clamping instead of rejecting
90
+ const runtime = createPreviewRuntime({
91
+ canvas: document.getElementById('canvas'),
92
+ source: `
93
+ function draw() {
94
+ background(30);
95
+ circle(width/2 + sin(t * TWO_PI) * 200, height/2, 100);
96
+ }
97
+ `,
98
+ mode: 'loop',
99
+ width: 1950,
100
+ height: 2400,
101
+ seed: 12345,
102
+ vars: [50, 75, 25],
103
+ totalFrames: 120,
104
+ onBudgetExceeded: (info) => console.warn('Budget exceeded:', info),
105
+ });
103
106
 
104
- ### Preview Budget (MANDATORY)
107
+ runtime.startLoop();
108
+ ```
105
109
 
106
- The runtime enforces hard limits to prevent browser freezes:
110
+ ### Detecting Runtime Mode
107
111
 
108
112
  ```typescript
109
- PREVIEW_BUDGET = {
110
- MAX_FRAMES: 30, // Maximum frames before auto-stop
111
- MAX_TOTAL_TIME_MS: 500, // Maximum execution time
112
- FRAME_STRIDE: 3, // Render every 3rd frame
113
- };
114
- ```
115
-
116
- If limits exceeded: rendering stops silently (no throw).
113
+ const stats = runtime.getPreviewStats();
117
114
 
118
- ### Canvas Scaling
115
+ console.log('Mode:', stats.mode); // 'preview'
116
+ console.log('Scale:', stats.scale); // 0.46
117
+ console.log('Frames:', stats.frames); // current frame count
118
+ console.log('Budget OK:', !stats.budgetExceeded);
119
+ ```
119
120
 
120
- Preview renderer scales large canvases automatically:
121
+ ### Handling Budget Limits
121
122
 
122
123
  ```typescript
123
- CANVAS_LIMITS = {
124
- MAX_DIMENSION: 900, // Max width/height in pixels
125
- MIN_DIMENSION: 100,
126
- };
124
+ const stats = runtime.getPreviewStats();
125
+
126
+ if (stats.budgetExceeded) {
127
+ console.log('Reason:', stats.budgetExceeded.reason);
128
+ // Options:
129
+ // 1. Simplify sketch (fewer iterations)
130
+ // 2. Increase maxFrames or maxTimeMs
131
+ // 3. Use budgetBehavior: 'degrade' to continue with frame skipping
132
+ }
127
133
  ```
128
134
 
129
- Aspect ratio is preserved. CSS scaling for display.
135
+ ---
130
136
 
131
- ### Runtime Mode Flag
137
+ ## Trust & Safety
132
138
 
133
- The preview runtime exposes a `mode` property:
139
+ ### Budgets Prevent Runaway Code
134
140
 
135
141
  ```typescript
136
- runtime.mode // 'preview'
142
+ const runtime = createPreviewRuntime({
143
+ canvas,
144
+ source: sketchCode,
145
+ mode: 'loop',
146
+ width: 1950,
147
+ height: 2400,
148
+
149
+ maxFrames: 1800, // Max frames before stop (default)
150
+ maxTimeMs: 300000, // Max 5 minutes (default)
151
+ budgetBehavior: 'stop', // 'stop' or 'degrade'
152
+ showOverlay: true, // Visual indicator when stopped
153
+
154
+ onBudgetExceeded: (info) => {
155
+ // No silent failures — you always know
156
+ console.log('Stopped:', info.reason);
157
+ },
158
+ });
137
159
  ```
138
160
 
139
- Use this to detect preview vs canonical rendering.
161
+ ### Observable State
140
162
 
141
- ---
163
+ ```typescript
164
+ const stats = runtime.getPreviewStats();
165
+ // {
166
+ // mode: 'preview',
167
+ // scale: 0.46,
168
+ // semanticWidth: 1950,
169
+ // semanticHeight: 2400,
170
+ // bufferWidth: 897,
171
+ // bufferHeight: 900,
172
+ // frames: 150,
173
+ // stride: 1,
174
+ // totalTimeMs: 18750,
175
+ // budgetExceeded?: { reason: 'frame_limit' | 'time_limit' }
176
+ // }
177
+ ```
142
178
 
143
- ## Install
179
+ ### What Can Differ vs Canonical
144
180
 
145
- ```bash
146
- npm install @nexart/ui-renderer
147
- ```
181
+ | Aspect | ui-renderer | codemode-sdk |
182
+ |--------|-------------|--------------|
183
+ | Resolution | Scaled to max 900px | Full resolution |
184
+ | Frame budget | 1800 frames / 5 min | Unlimited |
185
+ | Fine details | May be lost at scale | Pixel-perfect |
186
+ | Semantics | Consistent | Authoritative |
148
187
 
149
- Or use directly in HTML:
150
- ```html
151
- <script type="module">
152
- import { createSystem, previewSystem } from 'https://unpkg.com/@nexart/ui-renderer/dist/index.js';
153
- </script>
154
- ```
188
+ **Scaling may change fine details. Budgets may skip work. Core semantics are preserved.**
155
189
 
156
190
  ---
157
191
 
158
- ## Quick Start
192
+ ## Bounded Execution vs Canonical
193
+
194
+ | Aspect | Preview (this SDK) | Canonical (@nexart/codemode-sdk) |
195
+ |--------|-------------------|----------------------------------|
196
+ | **Purpose** | Fast browser visuals | Authoritative rendering |
197
+ | **Resolution** | Max 900px | Full resolution |
198
+ | **Budget** | 1800 frames / 5 min | Unlimited |
199
+ | **Determinism** | Consistent | Guaranteed |
200
+ | **Use for** | Editors, dashboards, display | Minting, export, archival |
201
+
202
+ ---
159
203
 
160
- ### Code Mode Preview
204
+ ## Optional: Canonical Handoff
205
+
206
+ When you need to escalate to canonical rendering:
161
207
 
162
208
  ```typescript
163
- import { createSystem, previewSystem } from '@nexart/ui-renderer';
209
+ import { toCanonicalRequest } from '@nexart/ui-renderer';
210
+
211
+ const config = {
212
+ canvas,
213
+ source: sketchCode,
214
+ mode: 'loop',
215
+ width: 1950,
216
+ height: 2400,
217
+ seed: 12345
218
+ };
164
219
 
165
- const system = createSystem({
166
- type: 'code',
167
- mode: 'loop',
168
- width: 1950,
169
- height: 2400,
170
- totalFrames: 120,
171
- seed: 12345,
172
- vars: [50, 75, 25], // VAR[0..9] — values 0-100, padded with zeros
173
- source: `
174
- function setup() {
175
- noFill();
176
- stroke(0);
177
- }
178
- function draw() {
179
- background(246, 245, 242);
180
- var count = int(map(VAR[0], 0, 100, 5, 30));
181
- for (var i = 0; i < count; i++) {
182
- var x = width / 2 + cos(t * TWO_PI + i * 0.5) * map(VAR[1], 0, 100, 50, 400);
183
- var y = height / 2 + sin(t * TWO_PI + i * 0.3) * 200;
184
- ellipse(x, y, 50);
185
- }
186
- }
187
- `
188
- });
220
+ const req = toCanonicalRequest(config);
189
221
 
190
- const canvas = document.getElementById('canvas');
191
- const renderer = previewSystem(system, canvas);
192
- renderer.start();
222
+ // Pass to backend with @nexart/codemode-sdk:
223
+ // await fetch('/api/render', { body: JSON.stringify(req) });
193
224
  ```
194
225
 
195
- ### Static Mode (single frame)
226
+ ---
196
227
 
197
- ```typescript
198
- const staticSystem = createSystem({
199
- type: 'code',
200
- mode: 'static',
201
- width: 1950,
202
- height: 2400,
203
- seed: 12345,
204
- vars: [50, 50, 50],
205
- source: `
206
- function setup() {
207
- background(246, 245, 242);
208
- fill(0);
209
- var count = int(map(VAR[0], 0, 100, 10, 200));
210
- for (var i = 0; i < count; i++) {
211
- ellipse(random(width), random(height), random(10, 50));
212
- }
213
- }
214
- `
215
- });
228
+ ## Install
229
+
230
+ ```bash
231
+ npm install @nexart/ui-renderer
232
+ ```
216
233
 
217
- previewSystem(staticSystem, canvas).render();
234
+ Or use directly:
235
+ ```html
236
+ <script type="module">
237
+ import { createPreviewRuntime } from 'https://unpkg.com/@nexart/ui-renderer/dist/index.js';
238
+ </script>
218
239
  ```
219
240
 
220
241
  ---
221
242
 
222
243
  ## API Reference
223
244
 
224
- ### `createSystem(input)`
245
+ ### `createPreviewRuntime(config)` — Recommended
225
246
 
226
- Create a NexArt system for preview.
247
+ Create a bounded preview renderer.
227
248
 
228
249
  ```typescript
229
- const system = createSystem({
230
- type: 'code',
250
+ const runtime = createPreviewRuntime({
251
+ canvas: HTMLCanvasElement,
252
+ source: string, // p5-like sketch code
231
253
  mode: 'static' | 'loop',
232
254
  width: number,
233
255
  height: number,
234
- source: string, // Raw p5-like sketch code
235
- seed?: number, // PRNG seed
236
- totalFrames?: number, // Required for loop mode
237
- vars?: number[] // VAR[0..9] (0-10 values, 0-100 range, clamped)
256
+ seed?: number,
257
+ vars?: number[], // VAR[0..9] (0-100 range)
258
+ totalFrames?: number, // For loop mode (default: 120)
259
+
260
+ // Budget options
261
+ onBudgetExceeded?: (info: BudgetExceededInfo) => void,
262
+ budgetBehavior?: 'stop' | 'degrade',
263
+ showOverlay?: boolean,
264
+ maxFrames?: number,
265
+ maxTimeMs?: number,
238
266
  });
239
- ```
240
-
241
- ### `previewSystem(system, canvas, options?)`
242
-
243
- Render a preview to canvas.
244
267
 
245
- ```typescript
246
- const renderer = previewSystem(system, canvas, {
247
- showBadge: boolean // default: true — shows "⚠️ Preview" badge
248
- });
249
-
250
- renderer.render(); // Single frame
251
- renderer.start(); // Start loop
252
- renderer.stop(); // Stop loop
253
- renderer.destroy(); // Cleanup
268
+ runtime.startLoop(); // Start animation
269
+ runtime.stopLoop(); // Stop animation
270
+ runtime.renderStatic(); // Render single frame
271
+ runtime.getPreviewStats(); // Get current stats
272
+ runtime.previewScale; // Canvas scale factor
273
+ runtime.destroy(); // Clean up
254
274
  ```
255
275
 
256
- ### `validateSystem(input)`
276
+ ### `toCanonicalRequest(config)`
257
277
 
258
- Soft validation warns but doesn't throw for minor issues.
278
+ Generate a handoff object for `@nexart/codemode-sdk`:
259
279
 
260
280
  ```typescript
261
- const result = validateSystem(input);
262
- if (!result.valid) {
263
- console.log(result.errors); // Structural issues only
264
- }
281
+ const req = toCanonicalRequest(config);
282
+ // { seed, vars, code, settings, renderer: 'preview', uiRendererVersion }
265
283
  ```
266
284
 
267
285
  ### `getCapabilities()`
268
286
 
269
- Discover SDK capabilities for AI and tooling.
287
+ Discover SDK capabilities:
270
288
 
271
289
  ```typescript
272
- import { getCapabilities } from '@nexart/ui-renderer';
273
-
274
290
  const caps = getCapabilities();
275
- // {
276
- // version: '0.8.7',
277
- // isCanonical: false,
278
- // isArchival: false,
279
- // previewBudget: { MAX_FRAMES: 30, MAX_TOTAL_TIME_MS: 500, FRAME_STRIDE: 3 },
280
- // canvasLimits: { MAX_DIMENSION: 900 },
281
- // ...
282
- // }
291
+ // { version, isCanonical, previewBudget, canvasLimits, ... }
283
292
  ```
284
293
 
285
294
  ---
286
295
 
287
- ## Available Helpers
296
+ ## Troubleshooting
288
297
 
289
- The preview runtime includes all standard p5-like functions plus:
298
+ ### "My sketch stops animating"
290
299
 
291
- | Helper | Description |
292
- |--------|-------------|
293
- | `int(n)` | Convert to integer (Math.floor) |
294
- | `fract(n)` | Fractional part of number |
295
- | `sign(n)` | Sign of number |
296
- | `vec(x, y)` | Create 2D vector |
297
- | `polygon(x, y, r, n)` | Draw n-sided polygon |
298
- | `star(x, y, r1, r2, n)` | Draw n-pointed star |
299
- | `fbm(x, y, z, octaves)` | Fractal Brownian motion |
300
- | `easeIn(t)`, `easeOut(t)`, etc. | Easing functions |
301
-
302
- ### Control Functions
303
-
304
- | Function | Preview Behavior |
305
- |----------|------------------|
306
- | `noLoop()` | Stops preview loop (soft control) |
307
- | `loop()` | No-op in preview |
308
-
309
- ---
310
-
311
- ## Supported Element Types
312
-
313
- ### `background`
314
-
315
- Opinionated presets with guardrails.
300
+ Check `getPreviewStats().budgetExceeded`:
316
301
 
317
302
  ```typescript
318
- {
319
- type: 'background',
320
- style: 'gradient', // gradient, solid, noise, grain
321
- palette: 'warm' // warm, cool, neutral, vibrant
303
+ const stats = runtime.getPreviewStats();
304
+ if (stats.budgetExceeded) {
305
+ console.log('Stopped because:', stats.budgetExceeded.reason);
322
306
  }
323
307
  ```
324
308
 
325
- ### `primitive`
309
+ **Solutions:**
310
+ 1. Reduce sketch complexity
311
+ 2. Increase budget: `maxFrames: 3600` or `maxTimeMs: 600000`
312
+ 3. Use `budgetBehavior: 'degrade'` to continue with frame skipping
326
313
 
327
- Declarative generative components. **30 primitives available:**
314
+ ### "Canvas is too small"
328
315
 
329
- **Categories:**
330
- - `basic` — dots, lines, waves, stripes, circles, grid
331
- - `geometric` — polygons, diamonds, hexgrid, stars, concentricSquares
332
- - `radial` — spirals, rays, orbits, rings, arcs, radialLines, petals
333
- - `flow` — flow, particles, bubbles
334
- - `patterns` — crosshatch, chevrons, zigzag, weave, moire
335
- - `organic` — curves, noise, mesh, branches
316
+ Preview scales to max 900px for performance:
336
317
 
337
318
  ```typescript
338
- {
339
- type: 'primitive',
340
- name: 'spirals',
341
- count: 12,
342
- color: '#ffffff',
343
- motion: 'medium',
344
- strokeWeight: 'thin',
345
- opacity: 0.8
346
- }
319
+ const stats = runtime.getPreviewStats();
320
+ console.log('Buffer:', stats.bufferWidth, 'x', stats.bufferHeight);
321
+ console.log('Semantic:', stats.semanticWidth, 'x', stats.semanticHeight);
347
322
  ```
348
323
 
349
- ### `sketch`
324
+ Your sketch code sees original `width`/`height`. Canvas buffer is scaled.
350
325
 
351
- Raw Code Mode execution.
326
+ ### "Animation looks choppy"
352
327
 
353
- ```typescript
354
- {
355
- type: 'sketch',
356
- code: `
357
- function setup() { background(0); }
358
- function draw() { ellipse(width/2, height/2, 100); }
359
- `,
360
- normalize: true
361
- }
362
- ```
328
+ 1. Check if in degraded mode (skipping frames)
329
+ 2. Reduce sketch complexity
330
+ 3. Check browser performance
363
331
 
364
332
  ---
365
333
 
366
- ## VAR Handling (Soft)
367
-
368
- VAR[0..9] is an array of 10 protocol variables.
334
+ ## Available Helpers
369
335
 
370
- **Preview behavior (permissive):**
371
- - Input: 0-10 elements accepted (extras ignored with warning)
372
- - Values: Clamped to 0-100 (not rejected)
373
- - Invalid types: Replaced with 0 (not rejected)
374
- - Runtime: Always 10 elements (padded with zeros)
375
- - Access: Read-only
336
+ All standard p5-like functions included:
376
337
 
377
- ```typescript
378
- // Works in preview (clamped to 100)
379
- vars: [150, 50, 50] // VAR[0] becomes 100
338
+ | Helper | Description |
339
+ |--------|-------------|
340
+ | `int(n)` | Convert to integer |
341
+ | `fract(n)` | Fractional part |
342
+ | `vec(x, y)` | Create 2D vector |
343
+ | `polygon(x, y, r, n)` | Draw n-sided polygon |
344
+ | `star(x, y, r1, r2, n)` | Draw n-pointed star |
345
+ | `fbm(x, y, z, octaves)` | Fractal Brownian motion |
346
+ | `easeIn(t)`, `easeOut(t)` | Easing functions |
380
347
 
381
- // Works in preview (non-numbers become 0)
382
- vars: ['bad', 50, 50] // VAR[0] becomes 0
348
+ ---
383
349
 
384
- // Works in preview (extras ignored)
385
- vars: [1,2,3,4,5,6,7,8,9,10,11,12] // Uses first 10
386
- ```
350
+ ## Legacy API
387
351
 
388
- For strict validation, use `@nexart/codemode-sdk`.
352
+ Still supported for backward compatibility:
389
353
 
390
- ---
354
+ ```typescript
355
+ import { createSystem, previewSystem } from '@nexart/ui-renderer';
391
356
 
392
- ## What This SDK Does NOT Do
357
+ const system = createSystem({
358
+ type: 'code',
359
+ mode: 'loop',
360
+ width: 1950,
361
+ height: 2400,
362
+ source: sketchCode,
363
+ seed: 12345,
364
+ });
393
365
 
394
- | Not Done | Explanation |
395
- |----------|-------------|
396
- | Protocol enforcement | No pattern checking or validation errors |
397
- | Canonical output | Use @nexart/codemode-sdk for minting |
398
- | Determinism guarantee | Preview may vary slightly |
399
- | Full frame count | Limited to 30 frames max |
400
- | Full resolution | Limited to 900px max dimension |
366
+ const renderer = previewSystem(system, canvas);
367
+ renderer.start();
368
+ ```
401
369
 
402
370
  ---
403
371
 
@@ -412,6 +380,4 @@ For strict validation, use `@nexart/codemode-sdk`.
412
380
 
413
381
  ## License
414
382
 
415
- MIT License
416
-
417
- Copyright (c) 2024-2026 NexArt
383
+ MIT License — Copyright (c) 2024-2026 NexArt
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @nexart/ui-renderer v0.8.0 - Capabilities Discovery
2
+ * @nexart/ui-renderer v0.9.0 - Capabilities Discovery
3
3
  *
4
4
  * Exposes SDK capabilities for AI tools and builders.
5
5
  * Lightweight preview runtime — no protocol enforcement.