@nexart/codemode-sdk 1.8.0 → 1.8.2

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 (138) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/COMMERCIAL.md +41 -0
  3. package/LICENSE.md +5 -5
  4. package/README.md +250 -700
  5. package/dist/sdk/codemode/core-index.d.ts +6 -4
  6. package/dist/sdk/codemode/core-index.d.ts.map +1 -1
  7. package/dist/sdk/codemode/core-index.js +6 -4
  8. package/dist/{entry → sdk/codemode/entry}/browser.d.ts +5 -2
  9. package/dist/sdk/codemode/entry/browser.d.ts.map +1 -0
  10. package/dist/{entry → sdk/codemode/entry}/browser.js +10 -4
  11. package/dist/{entry → sdk/codemode/entry}/node.d.ts +2 -1
  12. package/dist/sdk/codemode/entry/node.d.ts.map +1 -0
  13. package/dist/{entry → sdk/codemode/entry}/node.js +2 -1
  14. package/dist/{runtime.d.ts → sdk/codemode/runtime.d.ts} +2 -2
  15. package/dist/sdk/codemode/runtime.d.ts.map +1 -0
  16. package/dist/{runtime.js → sdk/codemode/runtime.js} +3 -2
  17. package/dist/sdk/codemode/static-engine.d.ts.map +1 -1
  18. package/dist/sdk/codemode/static-engine.js +24 -11
  19. package/dist/sdk/codemode/version.d.ts +18 -0
  20. package/dist/sdk/codemode/version.d.ts.map +1 -0
  21. package/dist/sdk/codemode/version.js +17 -0
  22. package/examples/agent-quickstart.ts +159 -0
  23. package/examples/preflight-test.ts +1 -1
  24. package/package.json +4 -2
  25. package/dist/builder-manifest.d.ts +0 -79
  26. package/dist/builder-manifest.d.ts.map +0 -1
  27. package/dist/builder-manifest.js +0 -97
  28. package/dist/core-index.d.ts +0 -21
  29. package/dist/core-index.d.ts.map +0 -1
  30. package/dist/core-index.js +0 -26
  31. package/dist/engine.d.ts +0 -24
  32. package/dist/engine.d.ts.map +0 -1
  33. package/dist/engine.js +0 -67
  34. package/dist/entry/browser.d.ts.map +0 -1
  35. package/dist/entry/node.d.ts.map +0 -1
  36. package/dist/execute.d.ts +0 -46
  37. package/dist/execute.d.ts.map +0 -1
  38. package/dist/execute.js +0 -283
  39. package/dist/execution-sandbox.d.ts +0 -107
  40. package/dist/execution-sandbox.d.ts.map +0 -1
  41. package/dist/execution-sandbox.js +0 -207
  42. package/dist/index.d.ts +0 -31
  43. package/dist/index.d.ts.map +0 -1
  44. package/dist/index.js +0 -63
  45. package/dist/loop-engine.d.ts +0 -22
  46. package/dist/loop-engine.d.ts.map +0 -1
  47. package/dist/loop-engine.js +0 -229
  48. package/dist/noise-bridge.d.ts +0 -44
  49. package/dist/noise-bridge.d.ts.map +0 -1
  50. package/dist/noise-bridge.js +0 -68
  51. package/dist/noise-engine.d.ts +0 -74
  52. package/dist/noise-engine.d.ts.map +0 -1
  53. package/dist/noise-engine.js +0 -132
  54. package/dist/noise-sketches/fractalNoise.d.ts +0 -11
  55. package/dist/noise-sketches/fractalNoise.d.ts.map +0 -1
  56. package/dist/noise-sketches/fractalNoise.js +0 -121
  57. package/dist/noise-sketches/index.d.ts +0 -21
  58. package/dist/noise-sketches/index.d.ts.map +0 -1
  59. package/dist/noise-sketches/index.js +0 -28
  60. package/dist/p5-runtime.d.ts +0 -75
  61. package/dist/p5-runtime.d.ts.map +0 -1
  62. package/dist/p5-runtime.js +0 -1031
  63. package/dist/runtime.d.ts.map +0 -1
  64. package/dist/sdk/codemode/index.d.ts +0 -31
  65. package/dist/sdk/codemode/index.d.ts.map +0 -1
  66. package/dist/sdk/codemode/index.js +0 -63
  67. package/dist/sdk/codemode/noise-bridge.d.ts +0 -44
  68. package/dist/sdk/codemode/noise-bridge.d.ts.map +0 -1
  69. package/dist/sdk/codemode/noise-bridge.js +0 -68
  70. package/dist/sdk/codemode/noise-engine.d.ts +0 -74
  71. package/dist/sdk/codemode/noise-engine.d.ts.map +0 -1
  72. package/dist/sdk/codemode/noise-engine.js +0 -132
  73. package/dist/sdk/codemode/noise-sketches/fractalNoise.d.ts +0 -11
  74. package/dist/sdk/codemode/noise-sketches/fractalNoise.d.ts.map +0 -1
  75. package/dist/sdk/codemode/noise-sketches/fractalNoise.js +0 -121
  76. package/dist/sdk/codemode/noise-sketches/index.d.ts +0 -21
  77. package/dist/sdk/codemode/noise-sketches/index.d.ts.map +0 -1
  78. package/dist/sdk/codemode/noise-sketches/index.js +0 -28
  79. package/dist/shared/noiseSnapshot.d.ts +0 -59
  80. package/dist/shared/noiseSnapshot.d.ts.map +0 -1
  81. package/dist/shared/noiseSnapshot.js +0 -72
  82. package/dist/sound-bridge.d.ts +0 -89
  83. package/dist/sound-bridge.d.ts.map +0 -1
  84. package/dist/sound-bridge.js +0 -128
  85. package/dist/soundart-engine.d.ts +0 -87
  86. package/dist/soundart-engine.d.ts.map +0 -1
  87. package/dist/soundart-engine.js +0 -173
  88. package/dist/soundart-sketches/chladniBloom.d.ts +0 -3
  89. package/dist/soundart-sketches/chladniBloom.d.ts.map +0 -1
  90. package/dist/soundart-sketches/chladniBloom.js +0 -53
  91. package/dist/soundart-sketches/dualVortex.d.ts +0 -3
  92. package/dist/soundart-sketches/dualVortex.d.ts.map +0 -1
  93. package/dist/soundart-sketches/dualVortex.js +0 -67
  94. package/dist/soundart-sketches/geometryIllusion.d.ts +0 -3
  95. package/dist/soundart-sketches/geometryIllusion.d.ts.map +0 -1
  96. package/dist/soundart-sketches/geometryIllusion.js +0 -89
  97. package/dist/soundart-sketches/index.d.ts +0 -39
  98. package/dist/soundart-sketches/index.d.ts.map +0 -1
  99. package/dist/soundart-sketches/index.js +0 -72
  100. package/dist/soundart-sketches/isoflow.d.ts +0 -3
  101. package/dist/soundart-sketches/isoflow.d.ts.map +0 -1
  102. package/dist/soundart-sketches/isoflow.js +0 -60
  103. package/dist/soundart-sketches/loomWeave.d.ts +0 -3
  104. package/dist/soundart-sketches/loomWeave.d.ts.map +0 -1
  105. package/dist/soundart-sketches/loomWeave.js +0 -59
  106. package/dist/soundart-sketches/noiseTerraces.d.ts +0 -3
  107. package/dist/soundart-sketches/noiseTerraces.d.ts.map +0 -1
  108. package/dist/soundart-sketches/noiseTerraces.js +0 -53
  109. package/dist/soundart-sketches/orb.d.ts +0 -3
  110. package/dist/soundart-sketches/orb.d.ts.map +0 -1
  111. package/dist/soundart-sketches/orb.js +0 -50
  112. package/dist/soundart-sketches/pixelGlyphs.d.ts +0 -3
  113. package/dist/soundart-sketches/pixelGlyphs.d.ts.map +0 -1
  114. package/dist/soundart-sketches/pixelGlyphs.js +0 -72
  115. package/dist/soundart-sketches/prismFlowFields.d.ts +0 -3
  116. package/dist/soundart-sketches/prismFlowFields.d.ts.map +0 -1
  117. package/dist/soundart-sketches/prismFlowFields.js +0 -51
  118. package/dist/soundart-sketches/radialBurst.d.ts +0 -3
  119. package/dist/soundart-sketches/radialBurst.d.ts.map +0 -1
  120. package/dist/soundart-sketches/radialBurst.js +0 -60
  121. package/dist/soundart-sketches/resonantSoundBodies.d.ts +0 -3
  122. package/dist/soundart-sketches/resonantSoundBodies.d.ts.map +0 -1
  123. package/dist/soundart-sketches/resonantSoundBodies.js +0 -89
  124. package/dist/soundart-sketches/rings.d.ts +0 -11
  125. package/dist/soundart-sketches/rings.d.ts.map +0 -1
  126. package/dist/soundart-sketches/rings.js +0 -89
  127. package/dist/soundart-sketches/squares.d.ts +0 -3
  128. package/dist/soundart-sketches/squares.d.ts.map +0 -1
  129. package/dist/soundart-sketches/squares.js +0 -52
  130. package/dist/soundart-sketches/waveStripes.d.ts +0 -3
  131. package/dist/soundart-sketches/waveStripes.d.ts.map +0 -1
  132. package/dist/soundart-sketches/waveStripes.js +0 -44
  133. package/dist/static-engine.d.ts +0 -20
  134. package/dist/static-engine.d.ts.map +0 -1
  135. package/dist/static-engine.js +0 -157
  136. package/dist/types.d.ts +0 -191
  137. package/dist/types.d.ts.map +0 -1
  138. package/dist/types.js +0 -32
package/README.md CHANGED
@@ -1,25 +1,84 @@
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.2 (Protocol v1.2.0)**
4
+
5
+ A deterministic execution runtime for reproducible, verifiable computation.
6
+
7
+ ---
8
+
9
+ ## Which API Should I Use?
10
+
11
+ **Decision table for choosing the right entrypoint:**
12
+
13
+ | Your Goal | Use This | Import Path |
14
+ |-----------|----------|-------------|
15
+ | Deterministic random/noise in any environment | **`createRuntime()`** ✅ DEFAULT | `@nexart/codemode-sdk` |
16
+ | AI agent integration | **`createRuntime()`** ✅ DEFAULT | `@nexart/codemode-sdk` |
17
+ | Browser/React/Vite app | **`createRuntime()`** ✅ DEFAULT | `@nexart/codemode-sdk` |
18
+ | Server-side image rendering | `executeCodeMode()` | `@nexart/codemode-sdk/node` |
19
+ | Full p5.js-style canvas execution | `executeCodeMode()` | `@nexart/codemode-sdk/node` |
20
+
21
+ **`createRuntime()`** is the **default and recommended** API:
22
+ - ✅ Works in browser and Node.js
23
+ - ✅ No canvas dependency
24
+ - ✅ Agent-first design
25
+ - ✅ Strict mode enforcement
26
+ - ✅ Lightweight
27
+
28
+ **`executeCodeMode()`** is the **legacy / Node-only** API:
29
+ - Requires Node.js with `canvas` package
30
+ - Full p5.js-style execution environment
31
+ - Returns rendered PNG/MP4
32
+ - Use only when you need actual image/video output
33
+
34
+ ---
35
+
36
+ ## What This SDK Does
37
+
38
+ 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.
39
+
40
+ **Core guarantees:**
41
+ - Same `seed` + `vars` + `code` → identical output (always)
42
+ - Cross-environment stability (browser, Node.js, CI pipelines)
43
+ - Strict mode blocks non-deterministic APIs (`Math.random`, `Date.now`, etc.)
44
+ - Canonical state snapshots for replay and verification
45
+ - Stable digest for integrity verification
46
+
47
+ ---
48
+
49
+ ## Who This Is For
50
+
51
+ **Use this SDK if determinism is non-negotiable:**
52
+
53
+ - **On-chain generative art** — NFTs, archival renders, mint verification
54
+ - **Procedural games** — Open-world generation, replay systems, save states
55
+ - **Simulations** — Physics, agent-based models, reproducible experiments
56
+ - **Finance research** — Backtesting, Monte Carlo, reproducible analysis
57
+ - **Education labs** — Repeatable demonstrations, grading consistency
58
+
59
+ **Skip this SDK if you're building:**
60
+
61
+ - CRUD apps
62
+ - Dashboards
63
+ - E-commerce
64
+ - Typical web applications without reproducibility requirements
65
+
66
+ For most applications, seeded randomness is unnecessary complexity.
17
67
 
18
68
  ---
19
69
 
20
70
  ## For AI Coding Agents (Replit / Lovable / Claude Code)
21
71
 
22
- **ALWAYS use `createRuntime({ seed, strict: true })` for deterministic execution.**
72
+ **Always start with `createRuntime()` it is the default and recommended API.**
73
+
74
+ ### Quick Rules for AI Agents
75
+
76
+ 1. **Always use `createRuntime()`** — NOT `executeCodeMode()`
77
+ 2. **Never use `Math.random()` or `Date.now()`** — use `runtime.random()` instead
78
+ 3. **Always use `strict: true`** — unless you explicitly know why you aren't
79
+ 4. **See `examples/agent-quickstart.ts`** — copy-paste ready reference
80
+
81
+ ### Minimal Example
23
82
 
24
83
  ```typescript
25
84
  import { createRuntime } from "@nexart/codemode-sdk";
@@ -27,24 +86,94 @@ import { createRuntime } from "@nexart/codemode-sdk";
27
86
  const runtime = createRuntime({
28
87
  seed: "my-artwork-42",
29
88
  vars: [50, 75, 25],
30
- strict: true, // IMPORTANT: Throws on Math.random, Date.now, etc.
89
+ strict: true, // ALWAYS use strict: true — throws on non-deterministic APIs
31
90
  mode: "static"
32
91
  });
33
92
 
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
93
+ // Deterministic APIs (use these, not Math.random!)
94
+ const value = runtime.random(); // [0, 1)
95
+ const intVal = runtime.randomInt(0, 10); // integer in range
96
+ const n = runtime.noise(0.5, 0.5); // Perlin noise
38
97
 
39
- // Verify determinism
40
- console.log(runtime.digest()); // Stable hash for verification
41
- console.log(runtime.getState()); // Canonical state snapshot
98
+ // Execute with strict enforcement
99
+ const result = runtime.run(() => {
100
+ // Your deterministic code here
101
+ return runtime.random() * 100;
102
+ });
103
+
104
+ // Verification
105
+ console.log(runtime.digest()); // Stable hash for verification
106
+ console.log(runtime.getState()); // Canonical state snapshot for replay
107
+ ```
108
+
109
+ ### Strict Mode Explained
110
+
111
+ Strict mode protects determinism by intercepting non-deterministic APIs during `runtime.run()`:
112
+
113
+ ```typescript
114
+ runtime.run(() => {
115
+ Math.random(); // Throws: NEXART_STRICT: Non-deterministic API used: Math.random. Use runtime.random() instead.
116
+ Date.now(); // Throws: NEXART_STRICT: Non-deterministic API used: Date.now. Pass time as an input or use deterministic counters.
117
+ });
42
118
  ```
43
119
 
44
- **Strict mode throws actionable errors:**
45
- - `NEXART_STRICT: Non-deterministic API used: Math.random. Use runtime.random() instead.`
46
- - `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.`
120
+ **Why strict mode exists:**
121
+ - Determinism is the core guarantee same inputs must always produce same outputs
122
+ - AI agents often default to `Math.random()` before reading documentation
123
+ - Strict mode catches these mistakes immediately with actionable error messages
124
+ - Interception is **scoped to `runtime.run()`** — it does NOT globally mutate your application
125
+ - Globals are restored after execution
126
+
127
+ **When to use `strict: false`:**
128
+ - Almost never. Only if you're intentionally mixing deterministic and non-deterministic code.
129
+ - If you're not sure, use `strict: true`.
130
+
131
+ ---
132
+
133
+ ## Where This Fits
134
+
135
+ ```
136
+ ┌─────────────────────────────────────────────────────────┐
137
+ │ Your Application │
138
+ │ (React, Canvas, Three.js, game engine, simulation) │
139
+ └────────────────────────┬────────────────────────────────┘
140
+
141
+
142
+ ┌─────────────────────────────────────────────────────────┐
143
+ │ @nexart/codemode-sdk │
144
+ │ Deterministic runtime layer │
145
+ │ - Seeded PRNG (Mulberry32) │
146
+ │ - Seeded noise (Perlin) │
147
+ │ - Strict mode enforcement │
148
+ │ - State snapshots + digest │
149
+ └────────────────────────┬────────────────────────────────┘
150
+
151
+
152
+ ┌─────────────────────────────────────────────────────────┐
153
+ │ Output │
154
+ │ - Deterministic result │
155
+ │ - Verification digest │
156
+ │ - Replay state │
157
+ └─────────────────────────────────────────────────────────┘
158
+ ```
159
+
160
+ 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.
161
+
162
+ ---
163
+
164
+ ## Why Not Roll Your Own?
165
+
166
+ **What's easy:**
167
+ - Seeded PRNG (dozens of implementations exist)
168
+ - Noise libraries (simplex, Perlin, available everywhere)
169
+
170
+ **What's hard:**
171
+ - **Cross-environment stability** — Same seed producing same sequence across browser versions, Node.js versions, bundlers, and platforms
172
+ - **Strict enforcement** — Actually blocking `Math.random()` and `Date.now()` during execution, with actionable error messages
173
+ - **Replay and verification** — Canonical state snapshots that can reconstruct execution
174
+ - **Long-term drift resistance** — Guaranteeing identical output years later, not just today
175
+
176
+ 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
177
 
49
178
  ---
50
179
 
@@ -60,14 +189,14 @@ console.log(runtime.getState()); // Canonical state snapshot
60
189
  - `Math.random()` — use `runtime.random()` instead
61
190
  - `Date.now()` — pass time as input or use frame counters
62
191
  - `performance.now()` — use deterministic timing
63
- - External IO during deterministic runs (not supported)
192
+ - External IO during deterministic runs
64
193
 
65
194
  ---
66
195
 
67
- ## Why Not Just Use a PRNG?
196
+ ## Feature Comparison
68
197
 
69
- | Feature | Plain PRNG | NexArt Runtime |
70
- |---------|-----------|----------------|
198
+ | Feature | Plain PRNG | This SDK |
199
+ |---------|-----------|----------|
71
200
  | Seeded random | ✅ | ✅ |
72
201
  | Seeded noise | ❌ (separate lib) | ✅ built-in |
73
202
  | Strict mode (blocks entropy) | ❌ | ✅ |
@@ -77,8 +206,6 @@ console.log(runtime.getState()); // Canonical state snapshot
77
206
  | Replay/verification | Manual | Built-in |
78
207
  | Error messages for agents | ❌ | ✅ actionable |
79
208
 
80
- **The runtime provides a complete determinism layer, not just random numbers.**
81
-
82
209
  ---
83
210
 
84
211
  ## Environment Imports
@@ -89,64 +216,64 @@ console.log(runtime.getState()); // Canonical state snapshot
89
216
  | Node.js (general use) | `import { createRuntime } from "@nexart/codemode-sdk"` |
90
217
  | Node.js server rendering (canvas) | `import { executeCodeMode } from "@nexart/codemode-sdk/node"` |
91
218
 
92
- **The default import is always browser-safe.** Node-only features (`executeCodeMode`, `runStaticMode`) require explicit `/node` import.
219
+ **The default import is browser-safe.** Node-only features require explicit `/node` import.
93
220
 
94
221
  ---
95
222
 
96
- ## License
223
+ ## Used By
97
224
 
98
- **Free for:**
99
- - Experiments and prototypes
100
- - Personal projects
101
- - Open-source projects
225
+ - **NexArt** — Generative art platform
226
+ - **ByX** Curated collections
227
+ - **Frontierra** — External builder integration
102
228
 
103
- **Commercial production deployments require a license.** See [LICENSING.md](./LICENSING.md) for details.
229
+ These are examples the SDK is designed for any system requiring deterministic execution.
104
230
 
105
231
  ---
106
232
 
107
- ## PROTOCOL LOCK — v1.x
233
+ ## Protocol Stability
108
234
 
109
235
  | Property | Value |
110
236
  |----------|-------|
111
- | Protocol Name | NexArt Code Mode |
112
- | Version | v1.2.0 |
237
+ | Protocol Version | v1.2.0 |
113
238
  | Status | **STABLE** |
114
- | Phase | 3 |
115
- | Lock Date | January 2026 |
116
-
117
- **Core protocol surface is frozen. Any breaking change requires v2.0.0.**
239
+ | SDK Version | 1.8.2 |
118
240
 
119
- The following are locked and will not change in v1.x:
241
+ **Core protocol surface is frozen. Breaking changes require v2.0.0.**
120
242
 
243
+ The following are locked in v1.x:
121
244
  - 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)
245
+ - VAR[0..9] specification
246
+ - Determinism guarantee
124
247
  - 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)
248
+ - Random and noise behavior
249
+ - Forbidden patterns list
128
250
 
129
251
  ---
130
252
 
131
- A minimal, deterministic rendering engine for generative art.
253
+ ## Licensing
132
254
 
133
- ## Protocol Authority
255
+ Free for personal projects, experiments, research, and open-source.
134
256
 
135
- **This SDK is the single source of truth for Code Mode semantics.**
257
+ Commercial production deployments require a license.
136
258
 
137
- If someone asks: "How does Code Mode work in NexArt?"
259
+ See [COMMERCIAL.md](./COMMERCIAL.md) for details.
138
260
 
139
- The answer is: "Whatever @nexart/codemode-sdk does — that is the protocol."
261
+ ---
262
+
263
+ ## Installation
264
+
265
+ ```bash
266
+ npm install @nexart/codemode-sdk
267
+ ```
140
268
 
141
269
  ---
142
270
 
143
- ## What's New in v1.8.0
271
+ ## Runtime API
144
272
 
145
- **Agent-First Runtime Authority Layer**
273
+ ### `createRuntime(options)`
146
274
 
147
- This release introduces `createRuntime()` — an agent-first API designed for AI coding assistants to reliably execute deterministic code.
275
+ Create a deterministic runtime instance.
148
276
 
149
- ### New Runtime API
150
277
  ```typescript
151
278
  import { createRuntime } from "@nexart/codemode-sdk";
152
279
 
@@ -167,239 +294,52 @@ runtime.run(() => { ... }); // Execute with strict enforcement
167
294
  ```
168
295
 
169
296
  ### 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
297
 
210
- ### No Breaking Changes
211
- - Protocol behavior and determinism unchanged
212
- - API surface unchanged
213
- - Existing Node.js code continues to work
298
+ When `strict: true`, the runtime intercepts non-deterministic APIs during `run()`:
214
299
 
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
-
250
- The SDK will produce **byte-for-byte identical output** across all executions.
251
-
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
300
+ ```typescript
301
+ runtime.run(() => {
302
+ Math.random(); // Throws: NEXART_STRICT: Non-deterministic API used
303
+ });
274
304
  ```
275
305
 
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
- ```
306
+ Strict mode:
307
+ - Only applies during `runtime.run()` — non-invasive
308
+ - Does NOT globally mutate your application
309
+ - Provides actionable error messages
366
310
 
367
311
  ---
368
312
 
369
- ## Browser Usage (v1.7.0+)
313
+ ## Browser Usage
370
314
 
371
- For Vite, React, Next.js, or any browser environment, import from the browser-safe entry:
315
+ For Vite, React, Next.js, or any browser environment:
372
316
 
373
317
  ```typescript
374
318
  import {
319
+ createRuntime,
375
320
  runLoopMode,
376
321
  cancelLoopMode,
377
322
  createP5Runtime,
378
323
  validateCodeModeSource,
379
- PROTOCOL_IDENTITY,
380
- DEFAULT_CONFIG,
381
- } from '@nexart/codemode-sdk/browser';
324
+ } from '@nexart/codemode-sdk';
382
325
  ```
383
326
 
384
- **What's included in `@nexart/codemode-sdk/browser`:**
385
- - All types (RenderMode, EngineConfig, ExecuteCodeModeInput, etc.)
327
+ **What's included:**
328
+ - Runtime API (createRuntime)
386
329
  - P5 runtime (createP5Runtime, injectTimeVariables, injectProtocolVariables)
387
330
  - Loop engine (runLoopMode, cancelLoopMode)
388
331
  - Execution sandbox (FORBIDDEN_APIS, createSafeMath)
389
332
  - Validation (validateCodeModeSource)
390
- - Builder manifest (registerBuilderManifest)
391
333
 
392
334
  **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.
335
+ - `executeCodeMode` — Requires Node.js canvas
336
+ - `runStaticMode` — Requires Node.js canvas
397
337
 
398
338
  ---
399
339
 
400
- ## Node.js Usage (v1.7.0+)
340
+ ## Node.js Usage
401
341
 
402
- For server-side rendering, oracles, or CLI tools, import from the Node entry:
342
+ For server-side rendering, oracles, or CLI tools:
403
343
 
404
344
  ```typescript
405
345
  import {
@@ -410,27 +350,20 @@ import {
410
350
  } from '@nexart/codemode-sdk/node';
411
351
  ```
412
352
 
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
353
  **Requirements:**
419
354
  - Node.js 18+
420
- - `canvas` package installed for static mode (`npm install canvas`)
355
+ - `canvas` package for static mode
421
356
 
422
357
  ---
423
358
 
424
- ## Canonical API
359
+ ## Canonical Execution API
425
360
 
426
- ### `executeCodeMode(input: ExecuteCodeModeInput): Promise<ExecuteCodeModeResult>`
361
+ ### `executeCodeMode(input): Promise<Result>`
427
362
 
428
- **This is the official, canonical entry point for Code Mode execution.**
429
-
430
- All implementations MUST use this function.
363
+ For systems requiring p5.js-style execution with full protocol metadata:
431
364
 
432
365
  ```typescript
433
- import { executeCodeMode } from '@nexart/codemode-sdk';
366
+ import { executeCodeMode } from '@nexart/codemode-sdk/node';
434
367
 
435
368
  const result = await executeCodeMode({
436
369
  source: `
@@ -448,180 +381,24 @@ const result = await executeCodeMode({
448
381
  mode: 'static'
449
382
  });
450
383
 
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
- }
384
+ console.log(result.metadata.deterministic); // true
385
+ console.log(result.image); // PNG Blob
492
386
  ```
493
387
 
494
388
  ---
495
389
 
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
- }
589
- ```
590
-
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
- ---
608
-
609
390
  ## Execution Rules
610
391
 
611
392
  ### 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`
393
+ 1. `setup()` executes once
394
+ 2. `draw()` is NOT executed
395
+ 3. Canvas captured as PNG
396
+ 4. Time variables are 0
617
397
 
618
398
  ### 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
399
+ 1. `setup()` executes once
400
+ 2. `draw()` executes per frame
401
+ 3. Canvas cleared before each `draw()`
625
402
 
626
403
  **Time Variables:**
627
404
 
@@ -631,277 +408,50 @@ Get the resolved engine configuration.
631
408
  | `t` | float | Normalized time [0.0, 1.0) |
632
409
  | `time` | float | Elapsed seconds |
633
410
  | `tGlobal` | float | Alias for `t` |
411
+ | `totalFrames` | int | Total frames in loop |
634
412
 
635
413
  ---
636
414
 
637
- ## Forbidden Patterns — LOCKED v1.0.0
415
+ ## Forbidden Patterns
638
416
 
639
- The following 13 patterns are rejected with `[Code Mode Protocol Error]`:
417
+ The following are rejected with `[Code Mode Protocol Error]`:
640
418
 
641
419
  | Pattern | Reason |
642
420
  |---------|--------|
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
421
+ | `Math.random()` | Use seeded `random()` |
422
+ | `Date.now()` | Time-based entropy |
423
+ | `new Date()` | Time-based entropy |
424
+ | `performance.now()` | Timing entropy |
425
+ | `crypto.getRandomValues()` | Crypto randomness |
426
+ | `fetch()` | External IO |
427
+ | `setTimeout` | Async timing |
428
+ | `setInterval` | Async timing |
429
+ | `requestAnimationFrame` | Async timing |
430
+ | `document.*` | DOM access |
431
+ | `window.*` | DOM access |
432
+ | `import` | External imports |
433
+ | `require()` | External imports |
659
434
 
660
435
  ---
661
436
 
662
- ## Example: Static Mode
663
-
664
- ```typescript
665
- import { createEngine } from './codemode';
666
-
667
- const engine = createEngine({ mode: 'static' });
437
+ ## Examples
668
438
 
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).
805
-
806
- ---
807
-
808
- ## Files
809
-
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
439
+ ```bash
440
+ npm run example:agent # Agent quickstart (RECOMMENDED for AI agents)
441
+ npm run example:basic # Basic usage
442
+ npm run example:verify # Determinism verification
827
443
  ```
828
444
 
829
445
  ---
830
446
 
831
- ## License
832
-
833
- MIT License
447
+ ## Changelog
834
448
 
835
- Copyright (c) 2024-2026 NexArt
449
+ See [CHANGELOG.md](./CHANGELOG.md) for version history.
836
450
 
837
451
  ---
838
452
 
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
- ---
453
+ ## About
901
454
 
902
- ## Future Work (Phase 4+)
455
+ This SDK is a reference implementation of a deterministic execution protocol designed for replay, verification, and long-term stability.
903
456
 
904
- - External asset loading (controlled)
905
- - WebGL/3D rendering support
906
- - GIF output option
907
- - GSL v1 SDK (protocol layer) — separate package
457
+ It prioritizes correctness and reproducibility over features.