@nexart/codemode-sdk 1.0.1 → 1.1.0

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.
Files changed (2) hide show
  1. package/README.md +267 -157
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,134 +1,219 @@
1
1
  # NexArt Code Mode Runtime SDK
2
2
 
3
- Version: 0.1.1
4
-
5
- A minimal, deterministic rendering engine for generative art.
3
+ **Version: 1.0.2 (Protocol v1.0.0)**
4
+
5
+ ╔══════════════════════════════════════════════════════════════════════════════╗
6
+ ║ @nexart/codemode-sdk — Canonical Code Mode Authority ║
7
+ ║ ║
8
+ ║ This SDK defines the official Code Mode execution surface. ║
9
+ ║ All implementations (NexArt, ByX, external) MUST use this SDK. ║
10
+ ║ ║
11
+ ║ Protocol: nexart ║
12
+ ║ Engine: codemode ║
13
+ ║ SDK Version: 1.0.2 ║
14
+ ║ Protocol Version: 1.0.0 ║
15
+ ║ Phase: 1 ║
16
+ ║ Enforcement: HARD ║
17
+ ╚══════════════════════════════════════════════════════════════════════════════╝
6
18
 
7
19
  ---
8
20
 
9
- > **This SDK enforces the NexArt Code Mode Runtime Execution Specification (v0.x).**
10
- >
11
- > **This is NOT the protocol-stable GSL v1.**
21
+ ## PROTOCOL LOCK v1.0.0
22
+
23
+ | Property | Value |
24
+ |----------|-------|
25
+ | Protocol Name | NexArt Code Mode |
26
+ | Version | v1.0.0 |
27
+ | Status | **HARD LOCKED** |
28
+ | Phase | 1 |
29
+ | Lock Date | December 2024 |
30
+
31
+ **This protocol surface is frozen. Any breaking change requires v2.0.0.**
32
+
33
+ The following are locked and will not change in v1.x:
34
+
35
+ - Execution model (Static and Loop modes)
36
+ - VAR[0..9] specification (0-10 read-only variables, missing indices return 0)
37
+ - Determinism guarantee (seed + VAR → identical output)
38
+ - Time semantics (t, frameCount, time, tGlobal)
39
+ - Random and noise behavior (seeded Mulberry32, Perlin)
40
+ - Forbidden patterns list (13 patterns)
41
+ - Canvas pre-initialization (no createCanvas)
12
42
 
13
43
  ---
14
44
 
15
- ## Install
45
+ A minimal, deterministic rendering engine for generative art.
16
46
 
17
- ```bash
18
- npm install @nexart/codemode-sdk
19
- ```
47
+ ## Protocol Authority
48
+
49
+ **This SDK is the single source of truth for Code Mode semantics.**
50
+
51
+ If someone asks: "How does Code Mode work in NexArt?"
52
+
53
+ The answer is: "Whatever @nexart/codemode-sdk does — that is the protocol."
20
54
 
21
55
  ---
22
56
 
23
- ## Usage
57
+ ## What's New in v1.0.2
24
58
 
25
- ```typescript
26
- import { createEngine } from '@nexart/codemode-sdk';
59
+ - **VAR input is now optional (0-10 elements)**
60
+ - Omit `vars` or pass `[]` for empty (defaults to all zeros)
61
+ - Input length must be 0-10 (throws if > 10)
62
+ - Values must be finite numbers in [0, 100] (throws if out of range)
63
+ - Runtime VAR is ALWAYS 10 elements (padded with zeros for consistency)
64
+ - **Backwards compatible**: existing code passing 10 elements works unchanged
27
65
 
28
- const engine = createEngine({ mode: 'static' });
66
+ ## v1.0.1
29
67
 
30
- await engine.run({
31
- code: `
32
- function setup() {
33
- background(255);
34
- fill(0);
35
- ellipse(width/2, height/2, 100);
36
- }
37
- `,
38
- onComplete: (result) => {
39
- console.log(result.type); // 'image'
40
- console.log(result.blob); // PNG Blob
41
- }
42
- });
43
- ```
68
+ - Protocol Lock section formalized with HARD LOCKED status
69
+ - VAR specification clarified with enforcement tables
70
+
71
+ ## v1.0.0 (Protocol Lock)
72
+
73
+ - **Protocol Lock**: Phase 1 execution surface is now LOCKED
74
+ - **Canonical Entry Point**: `executeCodeMode()` is the official execution API
75
+ - **Protocol Metadata**: All executions include protocol headers for verification
76
+ - **VAR[0..9] Protocol Variables**: First-class protocol inputs (read-only, 0-100)
77
+ - **Full CSS Color Support**: hex, rgb(), rgba(), hsl(), hsla()
78
+ - **Determinism Guarantee**: Same code + seed + vars = identical output
44
79
 
45
80
  ---
46
81
 
47
82
  ## What This SDK Is
48
83
 
49
- This SDK provides a headless runtime for executing p5.js-style generative art code and producing deterministic output:
84
+ This SDK provides the **canonical runtime** for executing p5.js-style generative art:
50
85
 
51
86
  - **Static Mode**: Executes `setup()` only, outputs PNG
52
87
  - **Loop Mode**: Frame-authoritative rendering, outputs MP4
88
+ - **Deterministic**: Seed-controlled randomness, no external state
89
+ - **Protocol-Compliant**: All outputs include verification metadata
90
+
91
+ The SDK enforces the **NexArt Code Mode Protocol v1.0.0** for reproducible, mint-safe generative art.
53
92
 
54
93
  ---
55
94
 
56
95
  ## What This SDK Is NOT
57
96
 
58
- - **Not a protocol layer** — Does not validate protocol claims, system hashes, or GSL v1
97
+ - **Not a suggestion** — This SDK IS the protocol, not a reference implementation
59
98
  - **Not a UI library** — No React components, no wallet integration
60
99
  - **Not an IPFS client** — Does not handle storage or minting
61
100
  - **Not p5.js** — Uses a minimal subset of p5.js-like functions
62
101
 
63
102
  ---
64
103
 
65
- ## Target Version
66
-
67
- **Code Mode Runtime v0.x**
104
+ ## Installation
68
105
 
69
- This SDK extracts the current NexArt Code Mode execution logic. Future versions may introduce:
70
- - GSL v1 SDK (protocol layer) — separate package
71
- - Extended p5.js compatibility
106
+ ```bash
107
+ npm install @nexart/codemode-sdk
108
+ ```
72
109
 
73
110
  ---
74
111
 
75
- ## API
76
-
77
- ### `createEngine(config: EngineConfig): Engine`
112
+ ## Canonical API
78
113
 
79
- Create a rendering engine instance.
114
+ ### `executeCodeMode(input: ExecuteCodeModeInput): Promise<ExecuteCodeModeResult>`
80
115
 
81
- ```typescript
82
- import { createEngine } from '@nexart/codemode-sdk';
83
-
84
- const engine = createEngine({
85
- mode: 'static', // 'static' | 'loop'
86
- width: 1950, // Optional, default: 1950
87
- height: 2400, // Optional, default: 2400
88
- duration: 2, // Loop mode only, 1-4 seconds
89
- fps: 30, // Loop mode only, default: 30
90
- });
91
- ```
116
+ **This is the official, canonical entry point for Code Mode execution.**
92
117
 
93
- ### `engine.run(options: RunOptions): Promise<void>`
94
-
95
- Execute code and produce output.
118
+ All implementations MUST use this function.
96
119
 
97
120
  ```typescript
98
- await engine.run({
99
- code: `
121
+ import { executeCodeMode } from '@nexart/codemode-sdk';
122
+
123
+ const result = await executeCodeMode({
124
+ source: `
100
125
  function setup() {
101
126
  background(255);
102
127
  fill(0);
103
- ellipse(width/2, height/2, 100);
128
+ let size = map(VAR[0], 0, 100, 50, 200);
129
+ ellipse(width/2, height/2, size);
104
130
  }
105
131
  `,
106
- onPreview: (canvas) => {
107
- // Optional: called with canvas after first frame
108
- },
109
- onProgress: (info) => {
110
- // Optional: progress updates
111
- console.log(info.message, info.percent + '%');
112
- },
113
- onComplete: (result) => {
114
- // Required: called with final result
115
- console.log(result.type); // 'image' | 'video'
116
- console.log(result.blob); // Blob
117
- },
118
- onError: (error) => {
119
- // Optional: called on error
120
- console.error(error);
121
- },
132
+ width: 1950,
133
+ height: 2400,
134
+ seed: 12345,
135
+ vars: [50, 75, 0, 0, 0, 0, 0, 0, 0, 0],
136
+ mode: 'static'
122
137
  });
138
+
139
+ // Result includes protocol metadata
140
+ console.log(result.metadata.protocol); // 'nexart'
141
+ console.log(result.metadata.engine); // 'codemode'
142
+ console.log(result.metadata.protocolVersion); // '1.0.0'
143
+ console.log(result.metadata.deterministic); // true
144
+ console.log(result.image); // PNG Blob
145
+ ```
146
+
147
+ ### Input Parameters
148
+
149
+ | Parameter | Type | Required | Description |
150
+ |-----------|------|----------|-------------|
151
+ | `source` | `string` | ✅ | Code with setup() and optional draw() |
152
+ | `width` | `number` | ✅ | Canvas width in pixels |
153
+ | `height` | `number` | ✅ | Canvas height in pixels |
154
+ | `seed` | `number` | ✅ | Seed for deterministic randomness |
155
+ | `vars` | `number[]` | ❌ | VAR values (0-10 elements, 0-100 range), missing indices return 0 |
156
+ | `mode` | `'static' \| 'loop'` | ✅ | Execution mode |
157
+ | `totalFrames` | `number` | ⚠️ | Required for loop mode |
158
+
159
+ ### Result Structure
160
+
161
+ ```typescript
162
+ interface ExecuteCodeModeResult {
163
+ image?: Blob; // Static mode: PNG
164
+ video?: Blob; // Loop mode: MP4
165
+ frames?: ImageData[]; // Optional: raw frame data
166
+ metadata: {
167
+ protocol: 'nexart';
168
+ engine: 'codemode';
169
+ protocolVersion: '1.0.0';
170
+ phase: 1;
171
+ deterministic: true;
172
+ seed: number;
173
+ vars: number[];
174
+ width: number;
175
+ height: number;
176
+ mode: 'static' | 'loop';
177
+ totalFrames?: number;
178
+ }
179
+ }
123
180
  ```
124
181
 
125
- ### `engine.stop(): void`
182
+ ---
183
+
184
+ ## Protocol Variables (VAR[0..9]) — Protocol v1.0.0
126
185
 
127
- Cancel a running render (Loop mode only).
186
+ Protocol variables are first-class inputs that control artwork parameters.
128
187
 
129
- ### `engine.getConfig(): EngineConfig`
188
+ **VAR Specification (SDK v1.0.2):**
130
189
 
131
- Get the resolved engine configuration.
190
+ | Property | Value | Enforcement |
191
+ |----------|-------|-------------|
192
+ | Input count | 0-10 (VAR[0]..VAR[9]) | HARD — throws if > 10 |
193
+ | Runtime count | Always 10 | Padded with zeros |
194
+ | Type | finite number | HARD — throws if non-number |
195
+ | Range | 0-100 | HARD — throws if out of range |
196
+ | Mutability | Read-only | HARD — Proxy blocks writes |
197
+ | Injection | Before execution | Guaranteed |
198
+ | Lifecycle | Stable for entire render | Guaranteed |
199
+ | Default | All zeros | If not provided |
200
+
201
+ ```typescript
202
+ // Access in sketch code (missing indices return 0)
203
+ function setup() {
204
+ let density = map(VAR[0], 0, 100, 10, 200);
205
+ let speed = map(VAR[1], 0, 100, 0.5, 5);
206
+ // VAR[5] returns 0 if not provided
207
+ }
208
+ ```
209
+
210
+ **Rules (Protocol Law):**
211
+ - Input accepts 0-10 elements; runtime VAR is always 10 elements
212
+ - VAR is injected BEFORE code execution (padded with zeros if needed)
213
+ - VAR values are READ-ONLY at runtime (Proxy-protected)
214
+ - Writing to VAR throws a protocol error
215
+ - Values MUST be in range 0-100 (throws if out of range)
216
+ - Same code + same seed + same VARs = identical output
132
217
 
133
218
  ---
134
219
 
@@ -160,83 +245,28 @@ Get the resolved engine configuration.
160
245
 
161
246
  ---
162
247
 
163
- ## Forbidden Patterns
164
-
165
- These patterns will throw errors:
166
-
167
- - `createCanvas()` Canvas is pre-initialized by the SDK
168
- - `setTimeout()`, `setInterval()`, `requestAnimationFrame()` — Async timing breaks determinism
169
- - `noLoop()` in Loop Mode Incompatible with frame capture
170
-
171
- ---
172
-
173
- ## Example: Static Mode
174
-
175
- ```typescript
176
- import { createEngine } from '@nexart/codemode-sdk';
177
-
178
- const engine = createEngine({ mode: 'static' });
179
-
180
- await engine.run({
181
- code: `
182
- function setup() {
183
- background(30);
184
- noStroke();
185
- for (let i = 0; i < 100; i++) {
186
- fill(random(255), random(255), random(255));
187
- ellipse(random(width), random(height), 50);
188
- }
189
- }
190
- `,
191
- onComplete: (result) => {
192
- // result.type === 'image'
193
- // result.blob is a PNG Blob
194
- const url = URL.createObjectURL(result.blob);
195
- document.body.innerHTML = `<img src="${url}" />`;
196
- },
197
- });
198
- ```
199
-
200
- ---
201
-
202
- ## Example: Loop Mode
203
-
204
- ```typescript
205
- import { createEngine } from '@nexart/codemode-sdk';
206
-
207
- const engine = createEngine({
208
- mode: 'loop',
209
- duration: 2, // 2 second loop
210
- });
211
-
212
- await engine.run({
213
- code: `
214
- function setup() {
215
- // Called once
216
- }
217
-
218
- function draw() {
219
- background(30);
220
-
221
- // t goes from 0 to 1 over the loop duration
222
- let x = width/2 + cos(t * TWO_PI) * 200;
223
- let y = height/2 + sin(t * TWO_PI) * 200;
224
-
225
- fill(255);
226
- ellipse(x, y, 80);
227
- }
228
- `,
229
- onProgress: (info) => {
230
- console.log(info.message);
231
- },
232
- onComplete: (result) => {
233
- // result.type === 'video'
234
- // result.blob is an MP4 Blob
235
- const url = URL.createObjectURL(result.blob);
236
- document.body.innerHTML = `<video src="${url}" autoplay loop />`;
237
- },
238
- });
239
- ```
248
+ ## Forbidden Patterns — LOCKED v1.0.0
249
+
250
+ The following 13 patterns are rejected with `[Code Mode Protocol Error]`:
251
+
252
+ | Pattern | Reason |
253
+ |---------|--------|
254
+ | `setTimeout` | Async timing breaks determinism |
255
+ | `setInterval` | Async timing breaks determinism |
256
+ | `requestAnimationFrame` | Async timing breaks determinism |
257
+ | `Date.now()` | Time-based entropy forbidden |
258
+ | `new Date()` | Time-based entropy forbidden |
259
+ | `Math.random()` | Use seeded `random()` instead |
260
+ | `fetch()` | External IO forbidden |
261
+ | `XMLHttpRequest` | External IO forbidden |
262
+ | `createCanvas()` | Canvas is pre-initialized |
263
+ | `document.*` | DOM access forbidden |
264
+ | `window.*` | DOM access forbidden |
265
+ | `import` | External imports forbidden |
266
+ | `require()` | External imports forbidden |
267
+
268
+ Additionally in Loop Mode:
269
+ - `noLoop()` — Incompatible with frame capture
240
270
 
241
271
  ---
242
272
 
@@ -257,7 +287,17 @@ The SDK includes a minimal p5.js-like runtime with:
257
287
  `push`, `pop`, `translate`, `rotate`, `scale`, `resetMatrix`
258
288
 
259
289
  **Color:**
260
- `colorMode`, `color`, `lerpColor`
290
+ `colorMode`, `color`, `lerpColor`, `red`, `green`, `blue`, `alpha`, `hue`, `saturation`, `brightness`
291
+
292
+ **Color Formats:**
293
+ All of the following are accepted by `fill()`, `stroke()`, `background()`:
294
+ - Grayscale: `fill(128)`, `fill(128, 127)`
295
+ - RGB: `fill(255, 0, 0)`, `fill(255, 0, 0, 128)`
296
+ - Hex: `fill('#ff0000')`, `fill('#f00')`
297
+ - CSS: `fill('rgb(255,0,0)')`, `fill('rgba(255,0,0,0.5)')`, `fill('hsl(180,50%,50%)')`
298
+
299
+ **Protocol Variables:**
300
+ `VAR` — Array of 10 values (VAR[0] through VAR[9])
261
301
 
262
302
  **Math:**
263
303
  `random`, `noise`, `map`, `constrain`, `lerp`, `dist`, `mag`, `norm`
@@ -270,6 +310,69 @@ The SDK includes a minimal p5.js-like runtime with:
270
310
 
271
311
  ---
272
312
 
313
+ ## Frozen Execution Guarantees — v1.0.0
314
+
315
+ The following guarantees are LOCKED and will not change in v1.x:
316
+
317
+ | Guarantee | Description |
318
+ |-----------|-------------|
319
+ | Determinism | Same code + same seed + same VARs = identical output |
320
+ | Static Mode | `setup()` only, single PNG output |
321
+ | Loop Mode | Frame-authoritative, `draw()` per frame, MP4 output |
322
+ | Time Semantics | `t` ∈ [0,1), `frameCount` ∈ [0,totalFrames), `time` in seconds |
323
+ | Random | Seeded Mulberry32 PRNG via `random()` |
324
+ | Noise | Seeded Perlin noise via `noise()` |
325
+ | Canvas | Pre-initialized, no `createCanvas()` |
326
+ | VAR | Exactly 10 read-only protocol variables |
327
+ | Forbidden Patterns | 13 patterns rejected (see above) |
328
+
329
+ ---
330
+
331
+ ## External Builders
332
+
333
+ This SDK is designed for use by:
334
+
335
+ - **NexArt App**: The main generative art platform
336
+ - **ByX**: Curated collection system
337
+ - **External Builders**: Any platform consuming NexArt Code Mode
338
+
339
+ ### Integration Example
340
+
341
+ ```typescript
342
+ import { executeCodeMode } from '@nexart/codemode-sdk';
343
+
344
+ // Execute with explicit VAR values
345
+ const result = await executeCodeMode({
346
+ source: artistCode,
347
+ width: 1950,
348
+ height: 2400,
349
+ seed: 12345,
350
+ vars: [50, 75, 25, 0, 0, 0, 0, 0, 0, 0], // Exactly 10 values
351
+ mode: 'static'
352
+ });
353
+
354
+ // Result includes full protocol metadata for verification
355
+ const { image, metadata } = result;
356
+ console.log(metadata.protocolVersion); // '1.0.0'
357
+ console.log(metadata.deterministic); // true
358
+ ```
359
+
360
+ ### Error Handling
361
+
362
+ All protocol violations throw descriptive errors:
363
+
364
+ ```typescript
365
+ try {
366
+ await executeCodeMode({ ... });
367
+ } catch (error) {
368
+ // "[Code Mode Protocol Error] VAR array must have exactly 10 elements, got 5"
369
+ // "[Code Mode Protocol Error] Forbidden pattern: Math.random()"
370
+ console.error(error.message);
371
+ }
372
+ ```
373
+
374
+ ---
375
+
273
376
  ## Video Encoding
274
377
 
275
378
  Loop Mode requires server-side video encoding. The SDK calls:
@@ -278,7 +381,7 @@ Loop Mode requires server-side video encoding. The SDK calls:
278
381
  POST /api/encode-loop
279
382
  ```
280
383
 
281
- Ensure your server has this endpoint available, or provide your own encoding solution.
384
+ Ensure your server has this endpoint available (NexArt provides this).
282
385
 
283
386
  ---
284
387
 
@@ -288,6 +391,7 @@ Ensure your server has this endpoint available, or provide your own encoding sol
288
391
  @nexart/codemode-sdk/
289
392
  ├── index.ts # Main export
290
393
  ├── engine.ts # createEngine entry point
394
+ ├── execute.ts # Canonical executeCodeMode API
291
395
  ├── types.ts # TypeScript types
292
396
  ├── static-engine.ts # Static mode implementation
293
397
  ├── loop-engine.ts # Loop mode implementation
@@ -299,7 +403,13 @@ Ensure your server has this endpoint available, or provide your own encoding sol
299
403
 
300
404
  ## Changelog
301
405
 
302
- **0.1.1** — Fixed beginShape / vertex / endShape rendering bug. Vertex-based shapes (waves, spirals, Lissajous curves, hexagons) now render correctly and match nexart.xyz behavior.
406
+ **1.0.2** — VAR is now optional (0-10 elements). Missing indices return 0. Out-of-range throws.
407
+
408
+ **1.0.1** — Protocol Lock formalized. VAR specification clarified. CHANGELOG added.
409
+
410
+ **1.0.0** — Protocol Lock. Phase 1 execution surface HARD LOCKED. executeCodeMode() canonical API.
411
+
412
+ **0.1.1** — Fixed beginShape / vertex / endShape rendering bug.
303
413
 
304
414
  **0.1.0** — Initial release.
305
415
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexart/codemode-sdk",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "NexArt Code Mode Runtime SDK - Deterministic generative art rendering engine",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",