@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 +39 -0
- package/COMMERCIAL.md +41 -0
- package/README.md +185 -696
- package/package.json +3 -2
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
|
-
#
|
|
2
|
-
|
|
3
|
-
**Version: 1.8.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
**
|
|
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, //
|
|
53
|
+
strict: true, // Throws on Math.random, Date.now, etc.
|
|
31
54
|
mode: "static"
|
|
32
55
|
});
|
|
33
56
|
|
|
34
|
-
//
|
|
35
|
-
const value = runtime.random(); //
|
|
36
|
-
const intVal = runtime.randomInt(0, 10); //
|
|
37
|
-
const n = runtime.noise(x, y); //
|
|
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
|
-
//
|
|
40
|
-
console.log(runtime.digest());
|
|
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
|
-
|
|
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
|
|
132
|
+
- External IO during deterministic runs
|
|
64
133
|
|
|
65
134
|
---
|
|
66
135
|
|
|
67
|
-
##
|
|
136
|
+
## Feature Comparison
|
|
68
137
|
|
|
69
|
-
| Feature | Plain PRNG |
|
|
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
|
|
159
|
+
**The default import is browser-safe.** Node-only features require explicit `/node` import.
|
|
93
160
|
|
|
94
161
|
---
|
|
95
162
|
|
|
96
|
-
##
|
|
163
|
+
## Used By
|
|
97
164
|
|
|
98
|
-
**
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
- Open-source projects
|
|
165
|
+
- **NexArt** — Generative art platform
|
|
166
|
+
- **ByX** — Curated collections
|
|
167
|
+
- **Frontierra** — External builder integration
|
|
102
168
|
|
|
103
|
-
|
|
169
|
+
These are examples — the SDK is designed for any system requiring deterministic execution.
|
|
104
170
|
|
|
105
171
|
---
|
|
106
172
|
|
|
107
|
-
##
|
|
173
|
+
## Protocol Stability
|
|
108
174
|
|
|
109
175
|
| Property | Value |
|
|
110
176
|
|----------|-------|
|
|
111
|
-
| Protocol
|
|
112
|
-
| Version | v1.2.0 |
|
|
177
|
+
| Protocol Version | v1.2.0 |
|
|
113
178
|
| Status | **STABLE** |
|
|
114
|
-
|
|
|
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
|
-
|
|
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
|
|
123
|
-
- Determinism guarantee
|
|
185
|
+
- VAR[0..9] specification
|
|
186
|
+
- Determinism guarantee
|
|
124
187
|
- Time semantics (t, frameCount, time, tGlobal, totalFrames)
|
|
125
|
-
- Random and noise behavior
|
|
126
|
-
- Forbidden patterns list
|
|
127
|
-
- Canvas pre-initialization (no createCanvas)
|
|
188
|
+
- Random and noise behavior
|
|
189
|
+
- Forbidden patterns list
|
|
128
190
|
|
|
129
191
|
---
|
|
130
192
|
|
|
131
|
-
|
|
193
|
+
## Licensing
|
|
194
|
+
|
|
195
|
+
Free for personal projects, experiments, research, and open-source.
|
|
132
196
|
|
|
133
|
-
|
|
197
|
+
Commercial production deployments require a license.
|
|
134
198
|
|
|
135
|
-
|
|
199
|
+
See [COMMERCIAL.md](./COMMERCIAL.md) for details.
|
|
136
200
|
|
|
137
|
-
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Installation
|
|
138
204
|
|
|
139
|
-
|
|
205
|
+
```bash
|
|
206
|
+
npm install @nexart/codemode-sdk
|
|
207
|
+
```
|
|
140
208
|
|
|
141
209
|
---
|
|
142
210
|
|
|
143
|
-
##
|
|
211
|
+
## Runtime API
|
|
144
212
|
|
|
145
|
-
|
|
213
|
+
### `createRuntime(options)`
|
|
146
214
|
|
|
147
|
-
|
|
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
|
-
|
|
238
|
+
When `strict: true`, the runtime intercepts non-deterministic APIs during `run()`:
|
|
251
239
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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
|
-
|
|
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
|
|
253
|
+
## Browser Usage
|
|
370
254
|
|
|
371
|
-
For Vite, React, Next.js, or any browser environment
|
|
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
|
-
|
|
380
|
-
DEFAULT_CONFIG,
|
|
381
|
-
} from '@nexart/codemode-sdk/browser';
|
|
264
|
+
} from '@nexart/codemode-sdk';
|
|
382
265
|
```
|
|
383
266
|
|
|
384
|
-
**What's included
|
|
385
|
-
-
|
|
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` —
|
|
394
|
-
- `runStaticMode` — Requires Node.js canvas
|
|
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
|
|
280
|
+
## Node.js Usage
|
|
401
281
|
|
|
402
|
-
For server-side rendering, oracles, or CLI tools
|
|
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
|
|
295
|
+
- `canvas` package for static mode
|
|
421
296
|
|
|
422
297
|
---
|
|
423
298
|
|
|
424
|
-
## Canonical API
|
|
299
|
+
## Canonical Execution API
|
|
425
300
|
|
|
426
|
-
### `executeCodeMode(input
|
|
301
|
+
### `executeCodeMode(input): Promise<Result>`
|
|
427
302
|
|
|
428
|
-
|
|
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
|
-
//
|
|
452
|
-
console.log(result.
|
|
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
|
-
|
|
614
|
-
|
|
615
|
-
|
|
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
|
-
|
|
621
|
-
|
|
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
|
|
355
|
+
## Forbidden Patterns
|
|
638
356
|
|
|
639
|
-
The following
|
|
357
|
+
The following are rejected with `[Code Mode Protocol Error]`:
|
|
640
358
|
|
|
641
359
|
| Pattern | Reason |
|
|
642
360
|
|---------|--------|
|
|
643
|
-
| `
|
|
644
|
-
| `
|
|
645
|
-
| `
|
|
646
|
-
| `
|
|
647
|
-
| `
|
|
648
|
-
| `
|
|
649
|
-
| `
|
|
650
|
-
| `
|
|
651
|
-
| `
|
|
652
|
-
| `document.*` | DOM access
|
|
653
|
-
| `window.*` | DOM access
|
|
654
|
-
| `import` | External imports
|
|
655
|
-
| `require()` | External imports
|
|
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
|
-
##
|
|
377
|
+
## Examples
|
|
809
378
|
|
|
810
|
-
```
|
|
811
|
-
|
|
812
|
-
|
|
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
|
-
##
|
|
386
|
+
## Changelog
|
|
832
387
|
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
Copyright (c) 2024-2026 NexArt
|
|
388
|
+
See [CHANGELOG.md](./CHANGELOG.md) for version history.
|
|
836
389
|
|
|
837
390
|
---
|
|
838
391
|
|
|
839
|
-
##
|
|
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
|
-
|
|
394
|
+
This SDK is a reference implementation of a deterministic execution protocol designed for replay, verification, and long-term stability.
|
|
903
395
|
|
|
904
|
-
|
|
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.
|
|
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
|
-
"
|
|
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
|
},
|