@nexart/codemode-sdk 1.8.0 → 1.8.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/CHANGELOG.md CHANGED
@@ -4,6 +4,45 @@ All notable changes to @nexart/codemode-sdk will be documented in this file.
4
4
 
5
5
  ---
6
6
 
7
+ ## [1.8.1] — 2026-01-24
8
+
9
+ ### Changed — Documentation & Licensing Clarity
10
+
11
+ **Non-Breaking, Metadata-Only Release**
12
+
13
+ This release addresses external review feedback about documentation framing and licensing clarity. No runtime, API, or behavior changes.
14
+
15
+ #### Documentation Reframed
16
+ - **Removed app-specific framing** — SDK no longer positioned as "for Frontierra" or "for ByX"
17
+ - **Genre-based language** — Now describes use cases (generative art, games, simulations, research)
18
+ - **"Who this is for / Who this is not for"** section added for clarity
19
+ - **"Where this fits"** section explains architectural boundary
20
+ - **"Why not roll your own?"** section honestly addresses when to skip this SDK
21
+ - **"Used by"** section lists NexArt, ByX, Frontierra as examples (not defining use cases)
22
+ - **Removed "This SDK IS the protocol" language** — Now describes as "reference implementation"
23
+
24
+ #### Licensing Clarified
25
+ - **COMMERCIAL.md added** — Plain language licensing terms
26
+ - **Free for**: personal, experiments, research, open-source
27
+ - **Commercial production**: requires license
28
+ - **Contact**: licensing@nexart.xyz
29
+ - **No phase language, no future enforcement language**
30
+
31
+ #### Package Updates
32
+ - **Version**: 1.8.1
33
+ - **files**: Added COMMERCIAL.md
34
+ - **homepage**: Added to package.json
35
+
36
+ ### Unchanged
37
+
38
+ - No changes to runtime behavior
39
+ - No changes to APIs or exports
40
+ - No changes to protocol version (remains v1.2.0)
41
+ - No changes to determinism guarantees
42
+ - Full backward compatibility with v1.8.0
43
+
44
+ ---
45
+
7
46
  ## [1.8.0] — 2026-01-24
8
47
 
9
48
  ### Added — Agent-First Runtime Authority Layer
package/COMMERCIAL.md ADDED
@@ -0,0 +1,41 @@
1
+ # Commercial Licensing
2
+
3
+ ## @nexart/codemode-sdk
4
+
5
+ ---
6
+
7
+ ## Free Use
8
+
9
+ You may use this SDK at no cost for:
10
+
11
+ - **Personal projects** — Learning, hobby work, portfolio pieces
12
+ - **Experiments and prototypes** — Proof of concepts, demos, hackathons
13
+ - **Research and education** — Academic work, teaching, scientific research
14
+ - **Open-source projects** — Projects with source code publicly available under an OSI-approved license
15
+
16
+ ---
17
+
18
+ ## Commercial Use
19
+
20
+ Commercial production deployments require a license.
21
+
22
+ **Commercial use includes:**
23
+ - Products or services that generate revenue
24
+ - Internal tools used in commercial operations
25
+ - SaaS applications
26
+ - Games or simulations sold or monetized
27
+ - Enterprise deployments
28
+
29
+ ---
30
+
31
+ ## Get a License
32
+
33
+ Contact: **licensing@artnames.io**
34
+
35
+ We offer flexible licensing options for teams and enterprises.
36
+
37
+ ---
38
+
39
+ ## Questions?
40
+
41
+ If you're unsure whether your use case requires a license, reach out to licensing@artnames.io. We're happy to help.
package/README.md CHANGED
@@ -1,25 +1,48 @@
1
- # NexArt Code Mode Runtime SDK
2
-
3
- **Version: 1.8.0 (Protocol v1.2.0)**
4
-
5
- ╔══════════════════════════════════════════════════════════════════════════════╗
6
- ║ @nexart/codemode-sdk — Canonical Execution Surface ║
7
- ║ ║
8
- ║ This SDK IS the protocol. All implementations MUST use this SDK. ║
9
- ║ ║
10
- ║ Protocol: nexart ║
11
- ║ Engine: codemode ║
12
- ║ SDK Version: 1.8.0 ║
13
- ║ Protocol Version: 1.2.0 ║
14
- ║ Phase: 3 ║
15
- ║ Enforcement: HARD ║
16
- ╚══════════════════════════════════════════════════════════════════════════════╝
1
+ # @nexart/codemode-sdk
2
+
3
+ **Version: 1.8.1 (Protocol v1.2.0)**
4
+
5
+ A deterministic execution runtime for reproducible, verifiable computation.
6
+
7
+ ---
8
+
9
+ ## What This SDK Does
10
+
11
+ This SDK provides a **deterministic runtime layer** for executing code that must produce identical output given identical inputs — across environments, over time, and under verification.
12
+
13
+ **Core guarantees:**
14
+ - Same `seed` + `vars` + `code` → identical output (always)
15
+ - Cross-environment stability (browser, Node.js, CI pipelines)
16
+ - Strict mode blocks non-deterministic APIs (`Math.random`, `Date.now`, etc.)
17
+ - Canonical state snapshots for replay and verification
18
+ - Stable digest for integrity verification
19
+
20
+ ---
21
+
22
+ ## Who This Is For
23
+
24
+ **Use this SDK if determinism is non-negotiable:**
25
+
26
+ - **On-chain generative art** — NFTs, archival renders, mint verification
27
+ - **Procedural games** — Open-world generation, replay systems, save states
28
+ - **Simulations** — Physics, agent-based models, reproducible experiments
29
+ - **Finance research** — Backtesting, Monte Carlo, reproducible analysis
30
+ - **Education labs** — Repeatable demonstrations, grading consistency
31
+
32
+ **Skip this SDK if you're building:**
33
+
34
+ - CRUD apps
35
+ - Dashboards
36
+ - E-commerce
37
+ - Typical web applications without reproducibility requirements
38
+
39
+ For most applications, seeded randomness is unnecessary complexity.
17
40
 
18
41
  ---
19
42
 
20
43
  ## For AI Coding Agents (Replit / Lovable / Claude Code)
21
44
 
22
- **ALWAYS use `createRuntime({ seed, strict: true })` for deterministic execution.**
45
+ **Use `createRuntime({ seed, strict: true })` for deterministic execution.**
23
46
 
24
47
  ```typescript
25
48
  import { createRuntime } from "@nexart/codemode-sdk";
@@ -27,24 +50,70 @@ import { createRuntime } from "@nexart/codemode-sdk";
27
50
  const runtime = createRuntime({
28
51
  seed: "my-artwork-42",
29
52
  vars: [50, 75, 25],
30
- strict: true, // IMPORTANT: Throws on Math.random, Date.now, etc.
53
+ strict: true, // Throws on Math.random, Date.now, etc.
31
54
  mode: "static"
32
55
  });
33
56
 
34
- // Use runtime.random() instead of Math.random()
35
- const value = runtime.random(); // Deterministic [0, 1)
36
- const intVal = runtime.randomInt(0, 10); // Deterministic integer
37
- const n = runtime.noise(x, y); // Deterministic Perlin noise
57
+ // Deterministic APIs
58
+ const value = runtime.random(); // [0, 1)
59
+ const intVal = runtime.randomInt(0, 10); // integer in range
60
+ const n = runtime.noise(x, y); // Perlin noise
38
61
 
39
- // Verify determinism
40
- console.log(runtime.digest()); // Stable hash for verification
62
+ // Verification
63
+ console.log(runtime.digest()); // Stable hash
41
64
  console.log(runtime.getState()); // Canonical state snapshot
42
65
  ```
43
66
 
44
67
  **Strict mode throws actionable errors:**
45
68
  - `NEXART_STRICT: Non-deterministic API used: Math.random. Use runtime.random() instead.`
46
69
  - `NEXART_STRICT: Non-deterministic API used: Date.now. Pass time as an input or use deterministic counters.`
47
- - `NEXART_STRICT: Non-deterministic API used: performance.now.`
70
+
71
+ ---
72
+
73
+ ## Where This Fits
74
+
75
+ ```
76
+ ┌─────────────────────────────────────────────────────────┐
77
+ │ Your Application │
78
+ │ (React, Canvas, Three.js, game engine, simulation) │
79
+ └────────────────────────┬────────────────────────────────┘
80
+
81
+
82
+ ┌─────────────────────────────────────────────────────────┐
83
+ │ @nexart/codemode-sdk │
84
+ │ Deterministic runtime layer │
85
+ │ - Seeded PRNG (Mulberry32) │
86
+ │ - Seeded noise (Perlin) │
87
+ │ - Strict mode enforcement │
88
+ │ - State snapshots + digest │
89
+ └────────────────────────┬────────────────────────────────┘
90
+
91
+
92
+ ┌─────────────────────────────────────────────────────────┐
93
+ │ Output │
94
+ │ - Deterministic result │
95
+ │ - Verification digest │
96
+ │ - Replay state │
97
+ └─────────────────────────────────────────────────────────┘
98
+ ```
99
+
100
+ The SDK sits between your UI/framework and your output. It does not render, does not manage state, does not touch the DOM. It provides deterministic primitives.
101
+
102
+ ---
103
+
104
+ ## Why Not Roll Your Own?
105
+
106
+ **What's easy:**
107
+ - Seeded PRNG (dozens of implementations exist)
108
+ - Noise libraries (simplex, Perlin, available everywhere)
109
+
110
+ **What's hard:**
111
+ - **Cross-environment stability** — Same seed producing same sequence across browser versions, Node.js versions, bundlers, and platforms
112
+ - **Strict enforcement** — Actually blocking `Math.random()` and `Date.now()` during execution, with actionable error messages
113
+ - **Replay and verification** — Canonical state snapshots that can reconstruct execution
114
+ - **Long-term drift resistance** — Guaranteeing identical output years later, not just today
115
+
116
+ If you need a quick seeded random, use any PRNG. If you need guaranteed reproducibility across time, environments, and verification systems — that's what this SDK provides.
48
117
 
49
118
  ---
50
119
 
@@ -60,14 +129,14 @@ console.log(runtime.getState()); // Canonical state snapshot
60
129
  - `Math.random()` — use `runtime.random()` instead
61
130
  - `Date.now()` — pass time as input or use frame counters
62
131
  - `performance.now()` — use deterministic timing
63
- - External IO during deterministic runs (not supported)
132
+ - External IO during deterministic runs
64
133
 
65
134
  ---
66
135
 
67
- ## Why Not Just Use a PRNG?
136
+ ## Feature Comparison
68
137
 
69
- | Feature | Plain PRNG | NexArt Runtime |
70
- |---------|-----------|----------------|
138
+ | Feature | Plain PRNG | This SDK |
139
+ |---------|-----------|----------|
71
140
  | Seeded random | ✅ | ✅ |
72
141
  | Seeded noise | ❌ (separate lib) | ✅ built-in |
73
142
  | Strict mode (blocks entropy) | ❌ | ✅ |
@@ -77,8 +146,6 @@ console.log(runtime.getState()); // Canonical state snapshot
77
146
  | Replay/verification | Manual | Built-in |
78
147
  | Error messages for agents | ❌ | ✅ actionable |
79
148
 
80
- **The runtime provides a complete determinism layer, not just random numbers.**
81
-
82
149
  ---
83
150
 
84
151
  ## Environment Imports
@@ -89,64 +156,64 @@ console.log(runtime.getState()); // Canonical state snapshot
89
156
  | Node.js (general use) | `import { createRuntime } from "@nexart/codemode-sdk"` |
90
157
  | Node.js server rendering (canvas) | `import { executeCodeMode } from "@nexart/codemode-sdk/node"` |
91
158
 
92
- **The default import is always browser-safe.** Node-only features (`executeCodeMode`, `runStaticMode`) require explicit `/node` import.
159
+ **The default import is browser-safe.** Node-only features require explicit `/node` import.
93
160
 
94
161
  ---
95
162
 
96
- ## License
163
+ ## Used By
97
164
 
98
- **Free for:**
99
- - Experiments and prototypes
100
- - Personal projects
101
- - Open-source projects
165
+ - **NexArt** — Generative art platform
166
+ - **ByX** Curated collections
167
+ - **Frontierra** — External builder integration
102
168
 
103
- **Commercial production deployments require a license.** See [LICENSING.md](./LICENSING.md) for details.
169
+ These are examples the SDK is designed for any system requiring deterministic execution.
104
170
 
105
171
  ---
106
172
 
107
- ## PROTOCOL LOCK — v1.x
173
+ ## Protocol Stability
108
174
 
109
175
  | Property | Value |
110
176
  |----------|-------|
111
- | Protocol Name | NexArt Code Mode |
112
- | Version | v1.2.0 |
177
+ | Protocol Version | v1.2.0 |
113
178
  | Status | **STABLE** |
114
- | Phase | 3 |
115
- | Lock Date | January 2026 |
116
-
117
- **Core protocol surface is frozen. Any breaking change requires v2.0.0.**
179
+ | SDK Version | 1.8.1 |
118
180
 
119
- The following are locked and will not change in v1.x:
181
+ **Core protocol surface is frozen. Breaking changes require v2.0.0.**
120
182
 
183
+ The following are locked in v1.x:
121
184
  - Execution model (Static and Loop modes)
122
- - VAR[0..9] specification (0-10 read-only variables, missing indices return 0)
123
- - Determinism guarantee (seed + VAR → identical output)
185
+ - VAR[0..9] specification
186
+ - Determinism guarantee
124
187
  - Time semantics (t, frameCount, time, tGlobal, totalFrames)
125
- - Random and noise behavior (seeded Mulberry32, Perlin)
126
- - Forbidden patterns list (13 patterns)
127
- - Canvas pre-initialization (no createCanvas)
188
+ - Random and noise behavior
189
+ - Forbidden patterns list
128
190
 
129
191
  ---
130
192
 
131
- A minimal, deterministic rendering engine for generative art.
193
+ ## Licensing
194
+
195
+ Free for personal projects, experiments, research, and open-source.
132
196
 
133
- ## Protocol Authority
197
+ Commercial production deployments require a license.
134
198
 
135
- **This SDK is the single source of truth for Code Mode semantics.**
199
+ See [COMMERCIAL.md](./COMMERCIAL.md) for details.
136
200
 
137
- If someone asks: "How does Code Mode work in NexArt?"
201
+ ---
202
+
203
+ ## Installation
138
204
 
139
- The answer is: "Whatever @nexart/codemode-sdk does — that is the protocol."
205
+ ```bash
206
+ npm install @nexart/codemode-sdk
207
+ ```
140
208
 
141
209
  ---
142
210
 
143
- ## What's New in v1.8.0
211
+ ## Runtime API
144
212
 
145
- **Agent-First Runtime Authority Layer**
213
+ ### `createRuntime(options)`
146
214
 
147
- This release introduces `createRuntime()` — an agent-first API designed for AI coding assistants to reliably execute deterministic code.
215
+ Create a deterministic runtime instance.
148
216
 
149
- ### New Runtime API
150
217
  ```typescript
151
218
  import { createRuntime } from "@nexart/codemode-sdk";
152
219
 
@@ -167,239 +234,52 @@ runtime.run(() => { ... }); // Execute with strict enforcement
167
234
  ```
168
235
 
169
236
  ### Strict Mode
170
- - Throws actionable errors on `Math.random`, `Date.now`, `performance.now`
171
- - Only applies during `runtime.run()` — non-invasive
172
- - Error messages guide agents to correct usage
173
-
174
- ### Agent-First Documentation
175
- - "For AI Coding Agents" section at top of README
176
- - Determinism Contract with ✅/❌ checklist
177
- - PRNG comparison table
178
- - Environment import matrix
179
-
180
- ### Examples
181
- - `npm run example:basic` — Basic usage demonstration
182
- - `npm run example:verify` — Determinism verification tests
183
-
184
- ### No Breaking Changes
185
- - All existing APIs work unchanged
186
- - Default import remains browser-safe
187
- - Protocol version unchanged (v1.2.0)
188
-
189
- ---
190
-
191
- ## What's New in v1.7.0
192
-
193
- **Browser-Safe Entrypoint + Conditional Exports**
194
-
195
- This release makes the SDK reliably usable in browser environments (Vite/React) without any Node.js dependency leakage.
196
-
197
- ### New Entry Points
198
- - `@nexart/codemode-sdk/browser` — Browser-safe modules only (no Node.js dependencies)
199
- - `@nexart/codemode-sdk/node` — Full SDK including static-engine (requires `canvas` package)
200
-
201
- ### Package.json Conditional Exports
202
- - Default import (`.`) now uses conditional exports: browser gets browser entry, Node gets Node entry
203
- - Explicit subpaths: `./browser` and `./node` for direct control
204
-
205
- ### Why This Matters
206
- - AI agents and bundlers will no longer accidentally import Node.js modules in browser builds
207
- - Vite/React apps can safely import the SDK without "createRequire is not defined" errors
208
- - Server-side code gets full functionality including static image rendering
209
-
210
- ### No Breaking Changes
211
- - Protocol behavior and determinism unchanged
212
- - API surface unchanged
213
- - Existing Node.js code continues to work
214
-
215
- ---
216
-
217
- ## What's New in v1.6.0
218
-
219
- **Licensing & Builder Identity Scaffolding (Metadata Only)**
220
-
221
- This is a non-breaking, metadata-only release. No changes to execution or determinism.
222
-
223
- ### Licensing (Informational Only)
224
- - Added `LICENSE.md` with draft commercial licensing terms
225
- - Enforcement is NOT active — all usage currently permitted under MIT
226
-
227
- ### Builder Manifest Schema
228
- - Added `builder.manifest.schema.json` for optional builder attribution
229
- - Fields: `builder_id`, `project_name`, `contact`, `website`, `intended_use`
230
- - This file is **optional**, **not validated**, and **not loaded at runtime**
231
-
232
- ### Documentation
233
- - SDK positioned as "canonical execution surface"
234
- - Explicit determinism guarantees documented
235
- - Real product references (ByX, Frontierra)
236
-
237
- ---
238
-
239
- ## Determinism Guarantees
240
-
241
- **The NexArt Code Mode SDK guarantees deterministic output.**
242
-
243
- Given identical inputs:
244
- - Same `source` code
245
- - Same `seed`
246
- - Same `vars` array
247
- - Same `width` and `height`
248
- - Same `mode`
249
237
 
250
- The SDK will produce **byte-for-byte identical output** across all executions.
238
+ When `strict: true`, the runtime intercepts non-deterministic APIs during `run()`:
251
239
 
252
- ### What Breaks Determinism
253
-
254
- The following actions will break determinism and are **blocked** by the SDK:
255
-
256
- | Pattern | Reason | Enforcement |
257
- |---------|--------|-------------|
258
- | `Math.random()` | Unseeded randomness | BLOCKED |
259
- | `Date.now()` | Time-based entropy | BLOCKED |
260
- | `new Date()` | Time-based entropy | BLOCKED |
261
- | `performance.now()` | Timing entropy | BLOCKED |
262
- | `crypto.getRandomValues()` | Crypto randomness | BLOCKED |
263
- | `fetch()` | External IO | BLOCKED |
264
- | External imports | Uncontrolled code | BLOCKED |
265
-
266
- Use `random()` (seeded) and `noise()` (seeded) for all randomness needs.
267
-
268
- ### Oracle Verification
269
-
270
- Before any release, run the determinism check:
271
-
272
- ```bash
273
- npx tsx scripts/check-determinism.ts
240
+ ```typescript
241
+ runtime.run(() => {
242
+ Math.random(); // Throws: NEXART_STRICT: Non-deterministic API used
243
+ });
274
244
  ```
275
245
 
276
- This compares output against a known oracle hash. If the hash changes without a protocol version bump, the release is invalid.
277
-
278
- ---
279
-
280
- ## Products Using This SDK
281
-
282
- - **NexArt**: Primary generative art platform
283
- - **ByX**: Curated collection system
284
- - **Frontierra**: External builder integration
285
-
286
- ---
287
-
288
- ## v1.5.1
289
-
290
- **Builder Manifest — Passive Attribution (Write-Only)**
291
-
292
- - `registerBuilderManifest(manifest?)` — Declare builder identity for future attribution
293
-
294
- The Builder Manifest is a declaration of intent, not a capability. Write-only, optional, non-enforced.
295
-
296
- ---
297
-
298
- ## v1.4.0 (Protocol v1.2.0)
299
-
300
- **Phase 3 — Pixel & Graphics**
301
-
302
- - **Vertex Functions**: `curveVertex(x, y)`, `bezierVertex(cx1, cy1, cx2, cy2, x, y)` for smooth curves
303
- - **Pixel System**: `loadPixels()`, `updatePixels()`, `pixels[]`, `get(x, y)`, `set(x, y, color)`
304
- - **Graphics System**: `createGraphics(w, h)`, `image(pg, x, y, w, h)` for offscreen rendering
305
- - **totalFrames**: Now injected into Loop Mode runtime
306
-
307
- ## v1.3.0 (Protocol v1.1.0)
308
-
309
- **Phase 2 — Expressive Extensions**
310
-
311
- - **Math Helpers**: `fract(n)`, `sign(n)`
312
- - **Vector Helpers**: `vec`, `vecAdd`, `vecSub`, `vecMult`, `vecMag`, `vecNorm`, `vecDist`
313
- - **Shape Helpers**: `polygon()`, `star()`
314
- - **Blend Modes**: `blendMode(NORMAL|ADD|MULTIPLY|SCREEN)`
315
- - **Noise Extensions**: `fbm()`, `ridgedNoise()`, `curlNoise()`
316
- - **Easing Functions**: `easeIn`, `easeOut`, `easeInOut`, `easeCubic`, `easeExpo`
317
-
318
- ## v1.2.0
319
-
320
- - Added `bezier()`, `curve()`, `strokeCap()`, `strokeJoin()`, `shearX()`, `shearY()`
321
- - Added text system: `text()`, `textSize()`, `textFont()`, `textAlign()`, `textWidth()`
322
- - Added `sq()`, `int()`, `TAU`, arc mode constants
323
-
324
- ## v1.1.1
325
-
326
- - **Critical Fix**: `random()` now uses seeded Mulberry32 PRNG (was using Math.random)
327
- - All randomness is now deterministic
328
-
329
- ## v1.0.x (Protocol Lock)
330
-
331
- - **Protocol Lock**: Phase 1 execution surface is now LOCKED
332
- - **Canonical Entry Point**: `executeCodeMode()` is the official execution API
333
- - **VAR[0..9] Protocol Variables**: First-class protocol inputs (read-only, 0-100)
334
- - **Determinism Guarantee**: Same code + seed + vars = identical output
335
-
336
- ---
337
-
338
- ## What This SDK Is
339
-
340
- This SDK provides the **canonical runtime** for executing p5.js-style generative art:
341
-
342
- - **Static Mode**: Executes `setup()` only, outputs PNG
343
- - **Loop Mode**: Frame-authoritative rendering, outputs MP4
344
- - **Deterministic**: Seed-controlled randomness, no external state
345
- - **Protocol-Compliant**: All outputs include verification metadata
346
-
347
- The SDK enforces the **NexArt Code Mode Protocol v1.2.0** for reproducible, mint-safe generative art.
348
-
349
- ---
350
-
351
- ## What This SDK Is NOT
352
-
353
- - **Not a suggestion** — This SDK IS the protocol, not a reference implementation
354
- - **Not a UI library** — No React components, no wallet integration
355
- - **Not an IPFS client** — Does not handle storage or minting
356
- - **Not p5.js** — Uses a minimal subset of p5.js-like functions
357
-
358
- ---
359
-
360
- ## Installation
361
-
362
- ```bash
363
- # Copy the sdk/codemode folder to your project
364
- cp -r sdk/codemode your-project/lib/codemode
365
- ```
246
+ Strict mode:
247
+ - Only applies during `runtime.run()` — non-invasive
248
+ - Does NOT globally mutate your application
249
+ - Provides actionable error messages
366
250
 
367
251
  ---
368
252
 
369
- ## Browser Usage (v1.7.0+)
253
+ ## Browser Usage
370
254
 
371
- For Vite, React, Next.js, or any browser environment, import from the browser-safe entry:
255
+ For Vite, React, Next.js, or any browser environment:
372
256
 
373
257
  ```typescript
374
258
  import {
259
+ createRuntime,
375
260
  runLoopMode,
376
261
  cancelLoopMode,
377
262
  createP5Runtime,
378
263
  validateCodeModeSource,
379
- PROTOCOL_IDENTITY,
380
- DEFAULT_CONFIG,
381
- } from '@nexart/codemode-sdk/browser';
264
+ } from '@nexart/codemode-sdk';
382
265
  ```
383
266
 
384
- **What's included in `@nexart/codemode-sdk/browser`:**
385
- - All types (RenderMode, EngineConfig, ExecuteCodeModeInput, etc.)
267
+ **What's included:**
268
+ - Runtime API (createRuntime)
386
269
  - P5 runtime (createP5Runtime, injectTimeVariables, injectProtocolVariables)
387
270
  - Loop engine (runLoopMode, cancelLoopMode)
388
271
  - Execution sandbox (FORBIDDEN_APIS, createSafeMath)
389
272
  - Validation (validateCodeModeSource)
390
- - Builder manifest (registerBuilderManifest)
391
273
 
392
274
  **What's NOT included (Node.js only):**
393
- - `executeCodeMode` — Uses static-engine which requires Node.js canvas
394
- - `runStaticMode` — Requires Node.js canvas package
395
-
396
- For static rendering in browser apps, use your server-side API endpoint.
275
+ - `executeCodeMode` — Requires Node.js canvas
276
+ - `runStaticMode` — Requires Node.js canvas
397
277
 
398
278
  ---
399
279
 
400
- ## Node.js Usage (v1.7.0+)
280
+ ## Node.js Usage
401
281
 
402
- For server-side rendering, oracles, or CLI tools, import from the Node entry:
282
+ For server-side rendering, oracles, or CLI tools:
403
283
 
404
284
  ```typescript
405
285
  import {
@@ -410,27 +290,20 @@ import {
410
290
  } from '@nexart/codemode-sdk/node';
411
291
  ```
412
292
 
413
- **What's included in `@nexart/codemode-sdk/node`:**
414
- - Everything from the browser entry
415
- - `executeCodeMode` — Canonical execution API
416
- - `runStaticMode` — Node.js static rendering (requires `canvas` package)
417
-
418
293
  **Requirements:**
419
294
  - Node.js 18+
420
- - `canvas` package installed for static mode (`npm install canvas`)
295
+ - `canvas` package for static mode
421
296
 
422
297
  ---
423
298
 
424
- ## Canonical API
299
+ ## Canonical Execution API
425
300
 
426
- ### `executeCodeMode(input: ExecuteCodeModeInput): Promise<ExecuteCodeModeResult>`
301
+ ### `executeCodeMode(input): Promise<Result>`
427
302
 
428
- **This is the official, canonical entry point for Code Mode execution.**
429
-
430
- All implementations MUST use this function.
303
+ For systems requiring p5.js-style execution with full protocol metadata:
431
304
 
432
305
  ```typescript
433
- import { executeCodeMode } from '@nexart/codemode-sdk';
306
+ import { executeCodeMode } from '@nexart/codemode-sdk/node';
434
307
 
435
308
  const result = await executeCodeMode({
436
309
  source: `
@@ -448,180 +321,24 @@ const result = await executeCodeMode({
448
321
  mode: 'static'
449
322
  });
450
323
 
451
- // Result includes protocol metadata
452
- console.log(result.metadata.protocol); // 'nexart'
453
- console.log(result.metadata.engine); // 'codemode'
454
- console.log(result.metadata.protocolVersion); // '1.2.0'
455
- console.log(result.metadata.deterministic); // true
456
- console.log(result.image); // PNG Blob
457
- ```
458
-
459
- ### Input Parameters
460
-
461
- | Parameter | Type | Required | Description |
462
- |-----------|------|----------|-------------|
463
- | `source` | `string` | ✅ | Code with setup() and optional draw() |
464
- | `width` | `number` | ✅ | Canvas width in pixels |
465
- | `height` | `number` | ✅ | Canvas height in pixels |
466
- | `seed` | `number` | ✅ | Seed for deterministic randomness |
467
- | `vars` | `number[]` | ❌ | VAR[0..9] values (0-100), defaults to all zeros |
468
- | `mode` | `'static' \| 'loop'` | ✅ | Execution mode |
469
- | `totalFrames` | `number` | ⚠️ | Required for loop mode |
470
-
471
- ### Result Structure
472
-
473
- ```typescript
474
- interface ExecuteCodeModeResult {
475
- image?: Blob; // Static mode: PNG
476
- video?: Blob; // Loop mode: MP4
477
- frames?: ImageData[]; // Optional: raw frame data
478
- metadata: {
479
- protocol: 'nexart';
480
- engine: 'codemode';
481
- protocolVersion: '1.0.0';
482
- phase: 1;
483
- deterministic: true;
484
- seed: number;
485
- vars: number[];
486
- width: number;
487
- height: number;
488
- mode: 'static' | 'loop';
489
- totalFrames?: number;
490
- }
491
- }
492
- ```
493
-
494
- ---
495
-
496
- ## Legacy API
497
-
498
- > ⚠️ **Note**: The `createEngine()` API is still supported but new implementations should use `executeCodeMode()`.
499
-
500
- ### `createEngine(config: EngineConfig): Engine`
501
-
502
- Create a rendering engine instance.
503
-
504
- ```typescript
505
- import { createEngine } from './codemode';
506
-
507
- const engine = createEngine({
508
- mode: 'static', // 'static' | 'loop'
509
- width: 1950, // Optional, default: 1950
510
- height: 2400, // Optional, default: 2400
511
- duration: 2, // Loop mode only, 1-4 seconds
512
- fps: 30, // Loop mode only, default: 30
513
- });
514
- ```
515
-
516
- ### `engine.run(options: RunOptions): Promise<void>`
517
-
518
- Execute code and produce output.
519
-
520
- ```typescript
521
- await engine.run({
522
- code: `
523
- function setup() {
524
- background(255);
525
- fill(0);
526
- // Use VAR for external control
527
- let size = map(VAR[0], 0, 100, 50, 200);
528
- ellipse(width/2, height/2, size);
529
- }
530
- `,
531
- seed: 12345, // Optional: seed for deterministic randomness
532
- vars: [50, 75, 0, 0, 0, 0, 0, 0, 0, 0], // Optional: VAR[0..9] values (0-100)
533
- onPreview: (canvas) => {
534
- // Optional: called with canvas after first frame
535
- },
536
- onProgress: (info) => {
537
- // Optional: progress updates
538
- console.log(info.message, info.percent + '%');
539
- },
540
- onComplete: (result) => {
541
- // Required: called with final result
542
- console.log(result.type); // 'image' | 'video'
543
- console.log(result.blob); // Blob
544
- },
545
- onError: (error) => {
546
- // Optional: called on error
547
- console.error(error);
548
- },
549
- });
550
- ```
551
-
552
- ### Protocol Variables (VAR[0..9]) — Protocol v1.0.0
553
-
554
- Protocol variables are first-class inputs that control artwork parameters.
555
-
556
- **VAR Specification (SDK v1.0.2):**
557
-
558
- | Property | Value | Enforcement |
559
- |----------|-------|-------------|
560
- | Input count | 0-10 (VAR[0]..VAR[9]) | HARD — throws if > 10 |
561
- | Runtime count | Always 10 | Padded with zeros |
562
- | Type | finite number | HARD — throws if non-number |
563
- | Range | 0-100 | HARD — throws if out of range |
564
- | Mutability | Read-only | HARD — Proxy blocks writes |
565
- | Injection | Before execution | Guaranteed |
566
- | Lifecycle | Stable for entire render | Guaranteed |
567
- | Default | All zeros | If not provided |
568
-
569
- ```typescript
570
- // Pass values when running (0-10 elements)
571
- await engine.run({
572
- code: myCode,
573
- vars: [80, 50, 25], // VAR[0]=80, VAR[1]=50, VAR[2]=25, VAR[3..9]=0
574
- onComplete: (result) => { /* ... */ },
575
- });
576
-
577
- // Or omit entirely (all zeros)
578
- await engine.run({
579
- code: myCode,
580
- onComplete: (result) => { /* ... */ },
581
- });
582
-
583
- // Access in sketch code
584
- function setup() {
585
- let density = map(VAR[0], 0, 100, 10, 200);
586
- let speed = map(VAR[1], 0, 100, 0.5, 5);
587
- // VAR[5] returns 0 if not provided
588
- }
324
+ console.log(result.metadata.deterministic); // true
325
+ console.log(result.image); // PNG Blob
589
326
  ```
590
327
 
591
- **Rules (Protocol Law):**
592
- - Input accepts 0-10 elements; runtime VAR is always 10 elements
593
- - VAR is injected BEFORE code execution (padded with zeros if needed)
594
- - VAR values are READ-ONLY at runtime (Proxy-protected)
595
- - Writing to VAR throws a protocol error
596
- - Values MUST be in range 0-100 (throws if out of range)
597
- - Same code + same seed + same VARs = identical output
598
-
599
- ### `engine.stop(): void`
600
-
601
- Cancel a running render (Loop mode only).
602
-
603
- ### `engine.getConfig(): EngineConfig`
604
-
605
- Get the resolved engine configuration.
606
-
607
328
  ---
608
329
 
609
330
  ## Execution Rules
610
331
 
611
332
  ### Static Mode
612
-
613
- 1. `setup()` is executed once
614
- 2. `draw()` is **NOT** executed
615
- 3. Canvas is captured as PNG
616
- 4. Time variables are all `0`
333
+ 1. `setup()` executes once
334
+ 2. `draw()` is NOT executed
335
+ 3. Canvas captured as PNG
336
+ 4. Time variables are 0
617
337
 
618
338
  ### Loop Mode
619
-
620
- 1. `setup()` is executed once
621
- 2. `draw()` is executed once per frame
622
- 3. Canvas is **cleared** before each `draw()` call
623
- 4. If artist calls `background()` in draw, it paints over the clear
624
- 5. No canvas persistence between frames
339
+ 1. `setup()` executes once
340
+ 2. `draw()` executes per frame
341
+ 3. Canvas cleared before each `draw()`
625
342
 
626
343
  **Time Variables:**
627
344
 
@@ -631,277 +348,49 @@ Get the resolved engine configuration.
631
348
  | `t` | float | Normalized time [0.0, 1.0) |
632
349
  | `time` | float | Elapsed seconds |
633
350
  | `tGlobal` | float | Alias for `t` |
351
+ | `totalFrames` | int | Total frames in loop |
634
352
 
635
353
  ---
636
354
 
637
- ## Forbidden Patterns — LOCKED v1.0.0
355
+ ## Forbidden Patterns
638
356
 
639
- The following 13 patterns are rejected with `[Code Mode Protocol Error]`:
357
+ The following are rejected with `[Code Mode Protocol Error]`:
640
358
 
641
359
  | Pattern | Reason |
642
360
  |---------|--------|
643
- | `setTimeout` | Async timing breaks determinism |
644
- | `setInterval` | Async timing breaks determinism |
645
- | `requestAnimationFrame` | Async timing breaks determinism |
646
- | `Date.now()` | Time-based entropy forbidden |
647
- | `new Date()` | Time-based entropy forbidden |
648
- | `Math.random()` | Use seeded `random()` instead |
649
- | `fetch()` | External IO forbidden |
650
- | `XMLHttpRequest` | External IO forbidden |
651
- | `createCanvas()` | Canvas is pre-initialized |
652
- | `document.*` | DOM access forbidden |
653
- | `window.*` | DOM access forbidden |
654
- | `import` | External imports forbidden |
655
- | `require()` | External imports forbidden |
656
-
657
- Additionally in Loop Mode:
658
- - `noLoop()` — Incompatible with frame capture
659
-
660
- ---
661
-
662
- ## Example: Static Mode
663
-
664
- ```typescript
665
- import { createEngine } from './codemode';
666
-
667
- const engine = createEngine({ mode: 'static' });
668
-
669
- await engine.run({
670
- code: `
671
- function setup() {
672
- background(30);
673
- noStroke();
674
- for (let i = 0; i < 100; i++) {
675
- fill(random(255), random(255), random(255));
676
- ellipse(random(width), random(height), 50);
677
- }
678
- }
679
- `,
680
- onComplete: (result) => {
681
- // result.type === 'image'
682
- // result.blob is a PNG Blob
683
- const url = URL.createObjectURL(result.blob);
684
- document.body.innerHTML = `<img src="${url}" />`;
685
- },
686
- });
687
- ```
688
-
689
- ---
690
-
691
- ## Example: Loop Mode
692
-
693
- ```typescript
694
- import { createEngine } from './codemode';
695
-
696
- const engine = createEngine({
697
- mode: 'loop',
698
- duration: 2, // 2 second loop
699
- });
700
-
701
- await engine.run({
702
- code: `
703
- function setup() {
704
- // Called once
705
- }
706
-
707
- function draw() {
708
- background(30);
709
-
710
- // t goes from 0 to 1 over the loop duration
711
- let x = width/2 + cos(t * TWO_PI) * 200;
712
- let y = height/2 + sin(t * TWO_PI) * 200;
713
-
714
- fill(255);
715
- ellipse(x, y, 80);
716
- }
717
- `,
718
- onProgress: (info) => {
719
- console.log(info.message);
720
- },
721
- onComplete: (result) => {
722
- // result.type === 'video'
723
- // result.blob is an MP4 Blob
724
- const url = URL.createObjectURL(result.blob);
725
- document.body.innerHTML = `<video src="${url}" autoplay loop />`;
726
- },
727
- });
728
- ```
729
-
730
- ---
731
-
732
- ## Supported Functions
733
-
734
- The SDK includes a comprehensive p5.js-like runtime with 130+ functions:
735
-
736
- **Drawing:**
737
- `background`, `clear`, `fill`, `noFill`, `stroke`, `noStroke`, `strokeWeight`, `strokeCap`, `strokeJoin`
738
-
739
- **Shapes:**
740
- `ellipse`, `circle`, `rect`, `square`, `line`, `point`, `triangle`, `quad`, `arc`, `bezier`, `curve`
741
-
742
- **Vertex (v1.4.0):**
743
- `beginShape`, `vertex`, `curveVertex`, `bezierVertex`, `endShape`
744
-
745
- **Shape Helpers (v1.3.0):**
746
- `polygon`, `star`
747
-
748
- **Transform:**
749
- `push`, `pop`, `translate`, `rotate`, `scale`, `resetMatrix`, `shearX`, `shearY`
750
-
751
- **Color:**
752
- `colorMode`, `color`, `lerpColor`, `red`, `green`, `blue`, `alpha`, `hue`, `saturation`, `brightness`
753
-
754
- **Text:**
755
- `text`, `textSize`, `textFont`, `textAlign`, `textWidth`
756
-
757
- **Blend Modes (v1.3.0):**
758
- `blendMode(NORMAL|ADD|MULTIPLY|SCREEN)`
759
-
760
- **Pixel System (v1.4.0):**
761
- `loadPixels`, `updatePixels`, `pixels[]`, `get`, `set`
762
-
763
- **Graphics (v1.4.0):**
764
- `createGraphics`, `image`
765
-
766
- **Color Formats:**
767
- All of the following are accepted by `fill()`, `stroke()`, `background()`:
768
- - Grayscale: `fill(128)`, `fill(128, 127)`
769
- - RGB: `fill(255, 0, 0)`, `fill(255, 0, 0, 128)`
770
- - Hex: `fill('#ff0000')`, `fill('#f00')`
771
- - CSS: `fill('rgb(255,0,0)')`, `fill('rgba(255,0,0,0.5)')`, `fill('hsl(180,50%,50%)')`
772
-
773
- **Protocol Variables:**
774
- `VAR` — Array of 10 values (VAR[0] through VAR[9])
775
-
776
- **Math:**
777
- `random`, `noise`, `map`, `constrain`, `lerp`, `dist`, `mag`, `norm`, `sq`, `int`, `fract`, `sign`
778
-
779
- **Vectors (v1.3.0):**
780
- `vec`, `vecAdd`, `vecSub`, `vecMult`, `vecMag`, `vecNorm`, `vecDist`
781
-
782
- **Noise Extensions (v1.3.0):**
783
- `fbm`, `ridgedNoise`, `curlNoise`
784
-
785
- **Easing (v1.3.0):**
786
- `easeIn`, `easeOut`, `easeInOut`, `easeCubic`, `easeExpo`
787
-
788
- **Trig:**
789
- `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `radians`, `degrees`
790
-
791
- **Constants:**
792
- `PI`, `TWO_PI`, `TAU`, `HALF_PI`, `QUARTER_PI`, `width`, `height`, `frameCount`, `totalFrames`
793
-
794
- ---
795
-
796
- ## Video Encoding
797
-
798
- Loop Mode requires server-side video encoding. The SDK calls:
799
-
800
- ```
801
- POST /api/encode-loop
802
- ```
803
-
804
- Ensure your server has this endpoint available (NexArt provides this).
361
+ | `Math.random()` | Use seeded `random()` |
362
+ | `Date.now()` | Time-based entropy |
363
+ | `new Date()` | Time-based entropy |
364
+ | `performance.now()` | Timing entropy |
365
+ | `crypto.getRandomValues()` | Crypto randomness |
366
+ | `fetch()` | External IO |
367
+ | `setTimeout` | Async timing |
368
+ | `setInterval` | Async timing |
369
+ | `requestAnimationFrame` | Async timing |
370
+ | `document.*` | DOM access |
371
+ | `window.*` | DOM access |
372
+ | `import` | External imports |
373
+ | `require()` | External imports |
805
374
 
806
375
  ---
807
376
 
808
- ## Files
377
+ ## Examples
809
378
 
810
- ```
811
- sdk/codemode/
812
- ├── entry/
813
- │ ├── browser.ts # Browser-safe entry point (v1.7.0)
814
- │ └── node.ts # Node.js entry point (v1.7.0)
815
- ├── index.ts # Main export (app integration layer)
816
- ├── core-index.ts # Core runtime exports
817
- ├── execute.ts # executeCodeMode canonical entry point
818
- ├── engine.ts # createEngine entry point (legacy)
819
- ├── types.ts # TypeScript types
820
- ├── static-engine.ts # Static mode implementation (Node.js)
821
- ├── loop-engine.ts # Loop mode implementation (browser)
822
- ├── p5-runtime.ts # p5.js-like runtime
823
- ├── execution-sandbox.ts # Determinism enforcement
824
- ├── builder-manifest.ts # Builder manifest (write-only)
825
- ├── CHANGELOG.md # Version history
826
- └── README.md # This file
379
+ ```bash
380
+ npm run example:basic # Basic usage
381
+ npm run example:verify # Determinism verification
827
382
  ```
828
383
 
829
384
  ---
830
385
 
831
- ## License
386
+ ## Changelog
832
387
 
833
- MIT License
834
-
835
- Copyright (c) 2024-2026 NexArt
388
+ See [CHANGELOG.md](./CHANGELOG.md) for version history.
836
389
 
837
390
  ---
838
391
 
839
- ## External Builders
840
-
841
- This SDK is designed for use by:
842
-
843
- - **NexArt App**: The main generative art platform
844
- - **ByX**: Curated collection system
845
- - **External Builders**: Any platform consuming NexArt Code Mode
846
-
847
- ### Integration Example
848
-
849
- ```typescript
850
- import { executeCodeMode } from '@nexart/codemode-sdk';
851
-
852
- // Execute with explicit VAR values
853
- const result = await executeCodeMode({
854
- source: artistCode,
855
- width: 1950,
856
- height: 2400,
857
- seed: 12345,
858
- vars: [50, 75, 25, 0, 0, 0, 0, 0, 0, 0], // Exactly 10 values
859
- mode: 'static'
860
- });
861
-
862
- // Result includes full protocol metadata for verification
863
- const { image, metadata } = result;
864
- console.log(metadata.protocolVersion); // '1.2.0'
865
- console.log(metadata.deterministic); // true
866
- ```
867
-
868
- ### Error Handling
869
-
870
- All protocol violations throw descriptive errors:
871
-
872
- ```typescript
873
- try {
874
- await executeCodeMode({ ... });
875
- } catch (error) {
876
- // "[Code Mode Protocol Error] VAR array must have exactly 10 elements, got 5"
877
- // "[Code Mode Protocol Error] Forbidden pattern: Math.random()"
878
- console.error(error.message);
879
- }
880
- ```
881
-
882
- ---
883
-
884
- ## Frozen Execution Guarantees — v1.0.0
885
-
886
- The following guarantees are LOCKED and will not change in v1.x:
887
-
888
- | Guarantee | Description |
889
- |-----------|-------------|
890
- | Determinism | Same code + same seed + same VARs = identical output |
891
- | Static Mode | `setup()` only, single PNG output |
892
- | Loop Mode | Frame-authoritative, `draw()` per frame, MP4 output |
893
- | Time Semantics | `t` ∈ [0,1), `frameCount` ∈ [0,totalFrames), `time` in seconds |
894
- | Random | Seeded Mulberry32 PRNG via `random()` |
895
- | Noise | Seeded Perlin noise via `noise()` |
896
- | Canvas | Pre-initialized, no `createCanvas()` |
897
- | VAR | Exactly 10 read-only protocol variables |
898
- | Forbidden Patterns | 13 patterns rejected (see above) |
899
-
900
- ---
392
+ ## About
901
393
 
902
- ## Future Work (Phase 4+)
394
+ This SDK is a reference implementation of a deterministic execution protocol designed for replay, verification, and long-term stability.
903
395
 
904
- - External asset loading (controlled)
905
- - WebGL/3D rendering support
906
- - GIF output option
907
- - GSL v1 SDK (protocol layer) — separate package
396
+ It prioritizes correctness and reproducibility over features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexart/codemode-sdk",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "description": "NexArt Code Mode SDK - Deterministic, reproducible, verifiable generative art runtime. Agent-first design for AI coding assistants.",
5
5
  "type": "module",
6
6
  "main": "./dist/entry/browser.js",
@@ -40,7 +40,7 @@
40
40
  "CHANGELOG.md",
41
41
  "CODE_MODE_PROTOCOL.md",
42
42
  "LICENSE.md",
43
- "LICENSING.md",
43
+ "COMMERCIAL.md",
44
44
  "builder.manifest.schema.json"
45
45
  ],
46
46
  "scripts": {
@@ -78,6 +78,7 @@
78
78
  "type": "git",
79
79
  "url": "https://github.com/artnames/nexart-codemode-sdk.git"
80
80
  },
81
+ "homepage": "https://github.com/artnames/nexart-codemode-sdk#readme",
81
82
  "publishConfig": {
82
83
  "access": "public"
83
84
  },