@nexart/codemode-sdk 1.5.0 → 1.6.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 (99) hide show
  1. package/CHANGELOG.md +326 -0
  2. package/CODE_MODE_PROTOCOL.md +471 -0
  3. package/LICENSE.md +62 -0
  4. package/README.md +296 -58
  5. package/builder.manifest.schema.json +62 -0
  6. package/dist/builder-manifest.d.ts +79 -0
  7. package/dist/builder-manifest.d.ts.map +1 -0
  8. package/dist/builder-manifest.js +97 -0
  9. package/dist/core-index.d.ts +21 -0
  10. package/dist/core-index.d.ts.map +1 -0
  11. package/dist/core-index.js +26 -0
  12. package/dist/engine.d.ts +17 -39
  13. package/dist/engine.d.ts.map +1 -1
  14. package/dist/engine.js +52 -253
  15. package/dist/execute.d.ts +46 -0
  16. package/dist/execute.d.ts.map +1 -0
  17. package/dist/execute.js +283 -0
  18. package/dist/execution-sandbox.d.ts +107 -0
  19. package/dist/execution-sandbox.d.ts.map +1 -0
  20. package/dist/execution-sandbox.js +207 -0
  21. package/dist/index.d.ts +24 -17
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +30 -16
  24. package/dist/loop-engine.d.ts +3 -0
  25. package/dist/loop-engine.d.ts.map +1 -1
  26. package/dist/loop-engine.js +17 -7
  27. package/dist/noise-bridge.d.ts +44 -0
  28. package/dist/noise-bridge.d.ts.map +1 -0
  29. package/dist/noise-bridge.js +68 -0
  30. package/dist/noise-engine.d.ts +74 -0
  31. package/dist/noise-engine.d.ts.map +1 -0
  32. package/dist/noise-engine.js +132 -0
  33. package/dist/noise-sketches/fractalNoise.d.ts +11 -0
  34. package/dist/noise-sketches/fractalNoise.d.ts.map +1 -0
  35. package/dist/noise-sketches/fractalNoise.js +121 -0
  36. package/dist/noise-sketches/index.d.ts +21 -0
  37. package/dist/noise-sketches/index.d.ts.map +1 -0
  38. package/dist/noise-sketches/index.js +28 -0
  39. package/dist/p5-runtime.d.ts +3 -1
  40. package/dist/p5-runtime.d.ts.map +1 -1
  41. package/dist/p5-runtime.js +2 -0
  42. package/dist/sound-bridge.d.ts +89 -0
  43. package/dist/sound-bridge.d.ts.map +1 -0
  44. package/dist/sound-bridge.js +128 -0
  45. package/dist/soundart-engine.d.ts +87 -0
  46. package/dist/soundart-engine.d.ts.map +1 -0
  47. package/dist/soundart-engine.js +173 -0
  48. package/dist/soundart-sketches/chladniBloom.d.ts +3 -0
  49. package/dist/soundart-sketches/chladniBloom.d.ts.map +1 -0
  50. package/dist/soundart-sketches/chladniBloom.js +53 -0
  51. package/dist/soundart-sketches/dualVortex.d.ts +3 -0
  52. package/dist/soundart-sketches/dualVortex.d.ts.map +1 -0
  53. package/dist/soundart-sketches/dualVortex.js +67 -0
  54. package/dist/soundart-sketches/geometryIllusion.d.ts +3 -0
  55. package/dist/soundart-sketches/geometryIllusion.d.ts.map +1 -0
  56. package/dist/soundart-sketches/geometryIllusion.js +89 -0
  57. package/dist/soundart-sketches/index.d.ts +39 -0
  58. package/dist/soundart-sketches/index.d.ts.map +1 -0
  59. package/dist/soundart-sketches/index.js +72 -0
  60. package/dist/soundart-sketches/isoflow.d.ts +3 -0
  61. package/dist/soundart-sketches/isoflow.d.ts.map +1 -0
  62. package/dist/soundart-sketches/isoflow.js +60 -0
  63. package/dist/soundart-sketches/loomWeave.d.ts +3 -0
  64. package/dist/soundart-sketches/loomWeave.d.ts.map +1 -0
  65. package/dist/soundart-sketches/loomWeave.js +59 -0
  66. package/dist/soundart-sketches/noiseTerraces.d.ts +3 -0
  67. package/dist/soundart-sketches/noiseTerraces.d.ts.map +1 -0
  68. package/dist/soundart-sketches/noiseTerraces.js +53 -0
  69. package/dist/soundart-sketches/orb.d.ts +3 -0
  70. package/dist/soundart-sketches/orb.d.ts.map +1 -0
  71. package/dist/soundart-sketches/orb.js +50 -0
  72. package/dist/soundart-sketches/pixelGlyphs.d.ts +3 -0
  73. package/dist/soundart-sketches/pixelGlyphs.d.ts.map +1 -0
  74. package/dist/soundart-sketches/pixelGlyphs.js +72 -0
  75. package/dist/soundart-sketches/prismFlowFields.d.ts +3 -0
  76. package/dist/soundart-sketches/prismFlowFields.d.ts.map +1 -0
  77. package/dist/soundart-sketches/prismFlowFields.js +51 -0
  78. package/dist/soundart-sketches/radialBurst.d.ts +3 -0
  79. package/dist/soundart-sketches/radialBurst.d.ts.map +1 -0
  80. package/dist/soundart-sketches/radialBurst.js +60 -0
  81. package/dist/soundart-sketches/resonantSoundBodies.d.ts +3 -0
  82. package/dist/soundart-sketches/resonantSoundBodies.d.ts.map +1 -0
  83. package/dist/soundart-sketches/resonantSoundBodies.js +89 -0
  84. package/dist/soundart-sketches/rings.d.ts +11 -0
  85. package/dist/soundart-sketches/rings.d.ts.map +1 -0
  86. package/dist/soundart-sketches/rings.js +89 -0
  87. package/dist/soundart-sketches/squares.d.ts +3 -0
  88. package/dist/soundart-sketches/squares.d.ts.map +1 -0
  89. package/dist/soundart-sketches/squares.js +52 -0
  90. package/dist/soundart-sketches/waveStripes.d.ts +3 -0
  91. package/dist/soundart-sketches/waveStripes.d.ts.map +1 -0
  92. package/dist/soundart-sketches/waveStripes.js +44 -0
  93. package/dist/static-engine.d.ts +7 -0
  94. package/dist/static-engine.d.ts.map +1 -1
  95. package/dist/static-engine.js +69 -14
  96. package/dist/types.d.ts +67 -5
  97. package/dist/types.d.ts.map +1 -1
  98. package/dist/types.js +1 -1
  99. package/package.json +26 -15
@@ -0,0 +1,471 @@
1
+ # Code Mode Protocol v1.2.0 — Phase 3
2
+
3
+ > **Status:** STABLE
4
+ > **Enforcement:** HARD
5
+ > **Effective Date:** January 2026
6
+
7
+ This document is **normative**. It defines the official Code Mode execution surface for NexArt Protocol. All implementations (NexArt app, ByX, external builders) MUST conform to this specification.
8
+
9
+ ---
10
+
11
+ ## 1. Protocol Identity
12
+
13
+ | Property | Value |
14
+ |----------|-------|
15
+ | Protocol | `nexart` |
16
+ | Engine | `codemode` |
17
+ | Version | `1.2.0` |
18
+ | Phase | `3` |
19
+ | Deterministic | `true` |
20
+
21
+ ---
22
+
23
+ ## 2. Execution Modes
24
+
25
+ ### 2.1 Static Mode
26
+ - Executes `setup()` once
27
+ - `draw()` is **NOT** executed
28
+ - Output: Single PNG image
29
+ - Time variables: All `0`
30
+
31
+ ### 2.2 Loop Mode
32
+ - Executes `setup()` once
33
+ - Executes `draw()` for each frame
34
+ - Canvas is cleared before each `draw()` call
35
+ - Blend mode resets to `NORMAL` before each `draw()` call
36
+ - Output: MP4 video (1-4 seconds, 30 FPS)
37
+ - Requires `totalFrames` to be specified
38
+
39
+ ---
40
+
41
+ ## 3. Protocol Variables (VAR[0..9])
42
+
43
+ ### 3.1 Definition
44
+ - Input: 0-10 elements allowed (protocol error if > 10)
45
+ - Runtime: ALWAYS 10 elements (padded with zeros)
46
+ - Type: `readonly number[]`
47
+ - Range: `0` to `100` (strict — protocol error if out of range)
48
+ - Default: All zeros `[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
49
+
50
+ ### 3.2 Access
51
+ ```javascript
52
+ // ✅ Allowed - reading (missing indices return 0)
53
+ let size = VAR[0]; // Returns provided value or 0
54
+ let opacity = map(VAR[1], 0, 100, 0, 255);
55
+
56
+ // ❌ Forbidden - writing (throws protocol error)
57
+ VAR[0] = 50; // [Code Mode Protocol Error] VAR is read-only
58
+ ```
59
+
60
+ ### 3.3 Enforcement
61
+ | Condition | Enforcement |
62
+ |-----------|-------------|
63
+ | Input length > 10 | HARD — throws protocol error |
64
+ | Value outside 0-100 | HARD — throws protocol error |
65
+ | Non-number value | HARD — throws protocol error |
66
+ | Write attempt | HARD — throws protocol error |
67
+ | Missing input | Runtime padded with zeros |
68
+
69
+ ---
70
+
71
+ ## 4. Supported Globals
72
+
73
+ ### 4.1 Canvas Environment
74
+ | Global | Type | Description |
75
+ |--------|------|-------------|
76
+ | `width` | `number` | Canvas width (default: 1950) |
77
+ | `height` | `number` | Canvas height (default: 2400) |
78
+
79
+ ### 4.2 Time Variables
80
+ | Global | Type | Description |
81
+ |--------|------|-------------|
82
+ | `frameCount` | `number` | Current frame (0, 1, 2, ...) |
83
+ | `t` | `number` | Normalized time [0.0, 1.0) |
84
+ | `time` | `number` | Elapsed seconds |
85
+ | `tGlobal` | `number` | Alias for `t` |
86
+ | `totalFrames` | `number` | Total frames in loop mode |
87
+
88
+ ### 4.3 Math Constants
89
+ | Global | Value |
90
+ |--------|-------|
91
+ | `PI` | `3.141592653589793` |
92
+ | `TWO_PI` | `6.283185307179586` |
93
+ | `TAU` | `6.283185307179586` |
94
+ | `HALF_PI` | `1.5707963267948966` |
95
+ | `QUARTER_PI` | `0.7853981633974483` |
96
+
97
+ ---
98
+
99
+ ## 5. Supported Functions
100
+
101
+ ### 5.1 Drawing Primitives
102
+ - `line(x1, y1, x2, y2)`
103
+ - `rect(x, y, w, h, [r])`
104
+ - `square(x, y, s, [r])` — Square shorthand
105
+ - `ellipse(x, y, w, h)`
106
+ - `circle(x, y, d)`
107
+ - `triangle(x1, y1, x2, y2, x3, y3)`
108
+ - `quad(x1, y1, x2, y2, x3, y3, x4, y4)`
109
+ - `arc(x, y, w, h, start, stop, [mode])`
110
+ - `point(x, y)`
111
+ - `beginShape()` / `vertex(x, y)` / `endShape([close])`
112
+ - `curveVertex(x, y)` — Add Catmull-Rom spline vertex
113
+ - `bezierVertex(cx1, cy1, cx2, cy2, x, y)` — Add cubic bezier vertex
114
+ - `bezier(x1, y1, cx1, cy1, cx2, cy2, x2, y2)`
115
+ - `curve(x1, y1, x2, y2, x3, y3, x4, y4)`
116
+
117
+ ### 5.1.1 Shape Helpers (v1.1)
118
+ - `polygon(cx, cy, radius, sides, [rotation])` — Regular polygon
119
+ - `star(cx, cy, innerRadius, outerRadius, points, [rotation])` — Star shape
120
+
121
+ Rules:
122
+ - Internally expand to `beginShape()` / `vertex()` / `endShape(CLOSE)`
123
+ - No hidden state
124
+ - No randomness (pure geometry)
125
+
126
+ ### 5.2 Style
127
+ - `fill(...)` — Supports all CSS color formats
128
+ - `noFill()`
129
+ - `stroke(...)` — Supports all CSS color formats
130
+ - `noStroke()`
131
+ - `strokeWeight(w)`
132
+ - `strokeCap(cap)` — `ROUND`, `SQUARE`, `PROJECT`
133
+ - `strokeJoin(join)` — `MITER`, `BEVEL`, `ROUND`
134
+ - `background(...)` — Supports all CSS color formats
135
+ - `clear()` — Clear canvas to transparent
136
+ - `colorMode(mode, [max1], [max2], [max3], [maxA])`
137
+
138
+ ### 5.2.1 Blend Modes (v1.1)
139
+ - `blendMode(mode)` — Set compositing mode
140
+
141
+ Supported modes (ONLY these are allowed):
142
+ | Mode | Canvas Equivalent |
143
+ |------|-------------------|
144
+ | `NORMAL` | `source-over` |
145
+ | `ADD` | `lighter` |
146
+ | `MULTIPLY` | `multiply` |
147
+ | `SCREEN` | `screen` |
148
+
149
+ Rules:
150
+ - Unsupported modes MUST throw a protocol error
151
+ - Blend mode resets to `NORMAL` before each `draw()` in Loop Mode
152
+ - No custom or dynamic modes
153
+
154
+ ### 5.2.2 Shape Mode Constants
155
+ - `CORNER` / `CENTER` / `CORNERS` / `RADIUS` — Rect/ellipse mode
156
+ - `CLOSE` — For `endShape(CLOSE)`
157
+ - `ROUND` / `SQUARE` / `PROJECT` — Stroke cap styles
158
+ - `MITER` / `BEVEL` — Stroke join styles
159
+ - `PIE` / `CHORD` / `OPEN` — Arc modes
160
+ - `LEFT` / `CENTER` / `RIGHT` — Horizontal alignment
161
+ - `TOP` / `BOTTOM` / `BASELINE` — Vertical alignment
162
+ - `NORMAL` / `ADD` / `MULTIPLY` / `SCREEN` — Blend modes
163
+
164
+ ### 5.3 Color Functions
165
+ - `color(...)` — Create color object
166
+ - `lerpColor(c1, c2, amt)` — Interpolate colors
167
+ - `red(c)` / `green(c)` / `blue(c)` / `alpha(c)` — Extract components
168
+ - `hue(c)` / `saturation(c)` / `brightness(c)` — HSB extraction
169
+
170
+ ### 5.4 Transforms
171
+ - `push()` / `pop()`
172
+ - `translate(x, y)`
173
+ - `rotate(angle)`
174
+ - `scale(s)` / `scale(sx, sy)`
175
+ - `resetMatrix()`
176
+ - `shearX(angle)` / `shearY(angle)`
177
+
178
+ ### 5.5 Random (Seeded)
179
+ - `random([min], [max])` — Seeded pseudo-random
180
+ - `randomSeed(seed)` — Set random seed
181
+ - `randomGaussian([mean], [sd])` — Seeded Gaussian
182
+
183
+ ### 5.6 Noise (Seeded)
184
+ - `noise(x, [y], [z])` — Seeded Perlin noise
185
+ - `noiseSeed(seed)` — Set noise seed
186
+ - `noiseDetail(octaves, [falloff])` — Configure noise
187
+
188
+ ### 5.6.1 Noise Extensions (v1.1)
189
+ - `fbm(x, y, [octaves], [falloff])` — Fractal Brownian Motion
190
+ - `ridgedNoise(x, y)` — Ridged/turbulent noise
191
+ - `curlNoise(x, y)` — Returns `{x, y}` curl noise vector
192
+
193
+ Rules:
194
+ - All use existing seeded `noise()` internally
195
+ - Pure functions with no internal state
196
+ - Deterministic for same inputs + seed
197
+
198
+ ### 5.7 Math Utilities
199
+ - `map(value, start1, stop1, start2, stop2)`
200
+ - `constrain(value, min, max)`
201
+ - `lerp(start, stop, amt)`
202
+ - `dist(x1, y1, x2, y2)`
203
+ - `mag(x, y)`
204
+ - `norm(value, start, stop)`
205
+ - `abs()` / `floor()` / `ceil()` / `round()` / `sqrt()` / `pow()` / `exp()` / `log()`
206
+ - `sin()` / `cos()` / `tan()` / `asin()` / `acos()` / `atan()` / `atan2()`
207
+ - `min()` / `max()`
208
+ - `radians(degrees)` / `degrees(radians)`
209
+
210
+ ### 5.7.1 Math Helpers (v1.1)
211
+ - `sq(n)` — Square: `n * n`
212
+ - `int(n)` — Floor to integer: `floor(n)`
213
+ - `fract(n)` — Fractional part: `n - floor(n)`
214
+ - `sign(n)` — Sign: `-1`, `0`, or `1`
215
+
216
+ Rules:
217
+ - Pure functions only
218
+ - No side effects
219
+ - Deterministic
220
+
221
+ ### 5.8 Vector Helpers (v1.1)
222
+
223
+ Vectors are **plain objects** `{ x: number, y: number }`. No classes or mutable state.
224
+
225
+ - `vec(x, y)` — Create vector `{ x, y }`
226
+ - `vecAdd(a, b)` — Add vectors: `{ x: a.x + b.x, y: a.y + b.y }`
227
+ - `vecSub(a, b)` — Subtract vectors: `{ x: a.x - b.x, y: a.y - b.y }`
228
+ - `vecMult(v, s)` — Scale vector: `{ x: v.x * s, y: v.y * s }`
229
+ - `vecMag(v)` — Magnitude: `sqrt(v.x² + v.y²)`
230
+ - `vecNorm(v)` — Normalize to unit vector
231
+ - `vecDist(a, b)` — Distance between two vectors
232
+
233
+ Rules:
234
+ - All functions return NEW objects (no mutation)
235
+ - No p5.Vector compatibility
236
+ - No methods on vector objects
237
+
238
+ ### 5.9 Easing Functions (v1.1)
239
+
240
+ All easing functions:
241
+ - Input: `t ∈ [0, 1]`
242
+ - Output: `∈ [0, 1]`
243
+ - Pure functions, no clamping side effects
244
+
245
+ - `easeIn(t)` — Quadratic ease in
246
+ - `easeOut(t)` — Quadratic ease out
247
+ - `easeInOut(t)` — Quadratic ease in-out
248
+ - `easeCubic(t)` — Cubic ease in-out
249
+ - `easeExpo(t)` — Exponential ease in-out
250
+
251
+ ### 5.10 Text
252
+ - `text(str, x, y)`
253
+ - `textSize(size)`
254
+ - `textFont(font)`
255
+ - `textAlign(horizAlign, [vertAlign])`
256
+ - `textWidth(str)`
257
+
258
+ ### 5.11 Image/Pixel (v1.2)
259
+ - `loadPixels()` — Load canvas pixels into `pixels[]` array
260
+ - `updatePixels()` — Write `pixels[]` array back to canvas
261
+ - `pixels[]` — RGBA pixel array (length = width × height × 4)
262
+ - `get(x, y)` — Get pixel color at (x, y) as RGBA array
263
+ - `set(x, y, color)` — Set pixel color at (x, y)
264
+
265
+ Rules:
266
+ - `pixels[]` is a flat array: `[R, G, B, A, R, G, B, A, ...]`
267
+ - Index formula: `i = (y * width + x) * 4`
268
+ - Must call `loadPixels()` before reading/modifying `pixels[]`
269
+ - Must call `updatePixels()` after modifying `pixels[]`
270
+ - Deterministic: no external state
271
+
272
+ ### 5.12 Offscreen Graphics (v1.2)
273
+ - `createGraphics(w, h)` — Create offscreen canvas
274
+
275
+ Returns a graphics object with:
276
+ - All drawing functions (rect, ellipse, line, etc.)
277
+ - All style functions (fill, stroke, etc.)
278
+ - All transform functions (push, pop, translate, etc.)
279
+ - `image(pg, x, y, [w], [h])` — Draw to main canvas
280
+
281
+ Rules:
282
+ - Offscreen graphics inherit seed from main canvas
283
+ - Each graphics object has independent state
284
+ - Deterministic: same execution = identical output
285
+
286
+ ---
287
+
288
+ ## 6. Forbidden Patterns
289
+
290
+ The following patterns are **explicitly forbidden** and MUST throw errors:
291
+
292
+ | Pattern | Reason |
293
+ |---------|--------|
294
+ | `setTimeout()` | Async timing breaks determinism |
295
+ | `setInterval()` | Async timing breaks determinism |
296
+ | `requestAnimationFrame()` | Async timing breaks determinism |
297
+ | `noLoop()` (in Loop Mode) | Incompatible with frame capture |
298
+ | `createCanvas()` | Canvas is pre-initialized |
299
+ | `fetch()` / `XMLHttpRequest` | External IO breaks determinism |
300
+ | `import` / `require` | No external modules |
301
+ | DOM manipulation | No direct DOM access |
302
+ | `Date.now()` / `new Date()` | Time-based entropy breaks determinism |
303
+ | `Math.random()` | Use `random()` instead (seeded) |
304
+ | `p5.Vector` | Use plain vector objects instead |
305
+ | Unsupported blend modes | Only NORMAL, ADD, MULTIPLY, SCREEN |
306
+
307
+ ---
308
+
309
+ ## 7. Determinism Guarantees
310
+
311
+ ### 7.1 Invariant
312
+ ```
313
+ Same code + Same seed + Same VARs = Identical output
314
+ ```
315
+
316
+ ### 7.2 Sources of Randomness
317
+ - **Allowed:** `random()`, `noise()` — Both are seeded
318
+ - **Forbidden:** `Math.random()`, `Date`, browser entropy
319
+
320
+ ### 7.3 Verification
321
+ Any execution can be verified by re-running with the same inputs.
322
+
323
+ ---
324
+
325
+ ## 8. Canonical Execution API
326
+
327
+ ### 8.1 Entry Point
328
+ ```typescript
329
+ executeCodeMode({
330
+ source: string,
331
+ width: number,
332
+ height: number,
333
+ seed: number,
334
+ vars?: number[],
335
+ mode: 'static' | 'loop',
336
+ totalFrames?: number
337
+ }) => Promise<ExecutionResult>
338
+ ```
339
+
340
+ ### 8.2 Result Structure
341
+ ```typescript
342
+ interface ExecutionResult {
343
+ image?: Blob; // Static mode: PNG
344
+ video?: Blob; // Loop mode: MP4
345
+ frames?: ImageData[]; // Optional: raw frames
346
+ metadata: {
347
+ protocol: 'nexart';
348
+ engine: 'codemode';
349
+ protocolVersion: '1.2.0';
350
+ phase: 3;
351
+ deterministic: true;
352
+ seed: number;
353
+ vars: number[];
354
+ width: number;
355
+ height: number;
356
+ mode: 'static' | 'loop';
357
+ totalFrames?: number;
358
+ }
359
+ }
360
+ ```
361
+
362
+ ---
363
+
364
+ ## 9. Implementation Requirements
365
+
366
+ ### 9.1 SDK Authority
367
+ - `@nexart/codemode-sdk` is the single source of truth
368
+ - NexArt app, ByX, and external clients MUST delegate to this SDK
369
+ - No other renderer may redefine Code Mode semantics
370
+
371
+ ### 9.2 Logging
372
+ All executions MUST log:
373
+ ```
374
+ [CodeMode] Rendered via @nexart/codemode-sdk (Protocol v1.2.0)
375
+ ```
376
+
377
+ ### 9.3 Error Handling
378
+ - Missing `draw()` in Loop Mode → Error
379
+ - Missing `totalFrames` in Loop Mode → Error
380
+ - VAR mutation attempt → Warning + Error log (no crash)
381
+ - Unsupported function → Clear error message
382
+ - Unsupported blend mode → Protocol error
383
+
384
+ ---
385
+
386
+ ## 10. Why These Were Added (v1.1 Rationale)
387
+
388
+ ### Expressive Power
389
+ - **Shape Helpers**: `polygon()` and `star()` reduce boilerplate for common patterns
390
+ - **Vector Helpers**: Enable clean geometric calculations without p5.Vector overhead
391
+ - **Easing Functions**: Essential for smooth animations in Loop Mode
392
+
393
+ ### Determinism
394
+ - **All new functions are pure**: No side effects, no hidden state
395
+ - **Blend modes are strictly limited**: Only 4 safe compositing modes
396
+ - **Noise extensions use seeded noise()**: No new sources of randomness
397
+
398
+ ### Cross-Runtime Portability
399
+ - **Plain vector objects**: Work identically in browser, Node.js, and headless environments
400
+ - **No DOM dependencies**: All functions work without a browser
401
+ - **Stateless math**: Every function can be verified independently
402
+
403
+ ---
404
+
405
+ ## 11. Future Phases
406
+
407
+ | Phase | Scope | Status |
408
+ |-------|-------|--------|
409
+ | Phase 3 | Pixel manipulation, offscreen buffers | ✅ COMPLETE (v1.2.0) |
410
+ | Phase 4 | External asset loading (controlled) | Planned |
411
+ | Phase 5 | WebGL/3D support | Planned |
412
+
413
+ Each phase requires a protocol version bump and formal specification.
414
+
415
+ ---
416
+
417
+ ## 12. Changelog
418
+
419
+ ### v1.2.0 (January 2026)
420
+ **Phase 3 — Pixel & Graphics**
421
+
422
+ Added:
423
+ - Vertex functions: `curveVertex(x, y)`, `bezierVertex(cx1, cy1, cx2, cy2, x, y)`
424
+ - Pixel system: `loadPixels()`, `updatePixels()`, `pixels[]`, `get(x, y)`, `set(x, y, color)`
425
+ - Graphics system: `createGraphics(w, h)`, `image(pg, x, y, w, h)`
426
+ - Time variable: `totalFrames` now injected in Loop Mode
427
+
428
+ Rules:
429
+ - All new functions are pure and deterministic
430
+ - Pixel manipulation follows p5.js semantics
431
+ - Offscreen graphics inherit seed from main canvas
432
+
433
+ ### v1.1.0 (January 2026)
434
+ **Phase 2 — Expressive Extensions**
435
+
436
+ Added:
437
+ - Math helpers: `fract(n)`, `sign(n)` (sq, int already in v1.0.1)
438
+ - Vector helpers: `vec`, `vecAdd`, `vecSub`, `vecMult`, `vecMag`, `vecNorm`, `vecDist`
439
+ - Shape helpers: `polygon(cx, cy, r, sides, rotation)`, `star(cx, cy, rIn, rOut, points, rotation)`
440
+ - Blend modes: `blendMode(NORMAL|ADD|MULTIPLY|SCREEN)`
441
+ - Noise extensions: `fbm(x, y, octaves, falloff)`, `ridgedNoise(x, y)`, `curlNoise(x, y)`
442
+ - Easing functions: `easeIn`, `easeOut`, `easeInOut`, `easeCubic`, `easeExpo`
443
+
444
+ Rules:
445
+ - All new functions are pure and deterministic
446
+ - Vectors are plain objects (no p5.Vector)
447
+ - Blend mode resets per frame in Loop Mode
448
+ - Unsupported blend modes throw protocol errors
449
+
450
+ ### v1.0.1 (January 2026)
451
+ - Added `square(x, y, s, [r])` to drawing primitives
452
+ - Added `clear()` to style functions
453
+ - Added `bezier()`, `curve()` to drawing primitives
454
+ - Added `strokeCap()`, `strokeJoin()` to style
455
+ - Added `shearX()`, `shearY()` to transforms
456
+ - Added `sq()`, `int()` to math
457
+ - Added text system: `text()`, `textSize()`, `textFont()`, `textAlign()`, `textWidth()`
458
+ - Documented shape mode constants
459
+ - Documented text alignment constants
460
+
461
+ ### v1.0.0 (December 2024)
462
+ - Initial locked specification
463
+ - VAR[0..9] read-only protocol variables
464
+ - Full CSS color support
465
+ - Seeded random/noise
466
+ - Static + Loop modes
467
+ - HARD enforcement enabled
468
+
469
+ ---
470
+
471
+ **End of Specification**
package/LICENSE.md ADDED
@@ -0,0 +1,62 @@
1
+ NexArt Code Mode SDK — License
2
+
3
+ Version: 1.6.0
4
+ Status: DRAFT — Enforcement Not Active
5
+
6
+
7
+
8
+ License Status
9
+
10
+ The NexArt Code Mode SDK is currently released under the MIT License.
11
+
12
+ At this time, all usage — including commercial usage — is permitted under the MIT License.
13
+
14
+ This document also serves as advance notice of a future commercial licensing model that may apply to certain uses of the NexArt Protocol.
15
+
16
+
17
+
18
+ Future Commercial Licensing (Not Active)
19
+
20
+ NexArt intends to introduce a separate commercial license for specific categories of usage in a future release.
21
+
22
+ Planned commercial usage categories may include (non-exhaustive):
23
+ • Minting NFTs for sale
24
+ • Revenue-generating applications
25
+ • Products or services that charge fees
26
+ • Enterprise or business deployments
27
+
28
+ Enforcement is NOT active.
29
+
30
+ No license keys, validation, usage tracking, or commercial restrictions are currently implemented.
31
+
32
+ Until enforcement is introduced in a future version, all usage remains governed solely by the MIT License below.
33
+
34
+
35
+
36
+ MIT License
37
+
38
+ Copyright (c) 2024–2026 NexArt
39
+
40
+ Permission is hereby granted, free of charge, to any person obtaining a copy
41
+ of this software and associated documentation files (the “Software”), to deal
42
+ in the Software without restriction, including without limitation the rights
43
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
44
+ copies of the Software, and to permit persons to whom the Software is
45
+ furnished to do so, subject to the following conditions:
46
+
47
+ The above copyright notice and this permission notice shall be included in all
48
+ copies or substantial portions of the Software.
49
+
50
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
56
+ SOFTWARE.
57
+
58
+
59
+
60
+ Contact
61
+
62
+ For future commercial licensing inquiries: arrotu@artnames.io