@nexart/codemode-sdk 1.5.1 → 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.
- package/CHANGELOG.md +37 -0
- package/LICENSE.md +62 -0
- package/README.md +83 -22
- package/builder.manifest.schema.json +62 -0
- package/dist/builder-manifest.d.ts +1 -1
- package/dist/builder-manifest.js +1 -1
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +4 -3
- package/dist/execution-sandbox.d.ts +107 -0
- package/dist/execution-sandbox.d.ts.map +1 -0
- package/dist/execution-sandbox.js +207 -0
- package/dist/loop-engine.d.ts +3 -0
- package/dist/loop-engine.d.ts.map +1 -1
- package/dist/loop-engine.js +17 -7
- package/dist/p5-runtime.d.ts +3 -1
- package/dist/p5-runtime.d.ts.map +1 -1
- package/dist/p5-runtime.js +2 -0
- package/dist/static-engine.d.ts +7 -0
- package/dist/static-engine.d.ts.map +1 -1
- package/dist/static-engine.js +69 -14
- package/dist/types.d.ts +28 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,43 @@ All notable changes to @nexart/codemode-sdk will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [1.6.0] — 2026-01-12
|
|
8
|
+
|
|
9
|
+
### Added — Licensing & Builder Identity Scaffolding
|
|
10
|
+
|
|
11
|
+
**Non-Breaking, Metadata-Only Release**
|
|
12
|
+
|
|
13
|
+
This release introduces scaffolding for future licensing and builder identity features. All additions are informational only — no behavior changes, no enforcement, no runtime validation.
|
|
14
|
+
|
|
15
|
+
#### Licensing (Informational Only)
|
|
16
|
+
- **LICENSE.md**: Draft commercial licensing terms with enforcement NOT active
|
|
17
|
+
- README section: "Commercial usage of NexArt Protocol requires a license. Enforcement is not active yet."
|
|
18
|
+
|
|
19
|
+
#### Builder Manifest Schema (Optional)
|
|
20
|
+
- **builder.manifest.schema.json**: JSON schema for optional builder attribution
|
|
21
|
+
- Fields: `builder_id`, `project_name`, `contact`, `website`, `intended_use`
|
|
22
|
+
- NOT validated, NOT loaded at runtime, NOT required
|
|
23
|
+
|
|
24
|
+
#### Documentation
|
|
25
|
+
- Positioned SDK as "canonical execution surface"
|
|
26
|
+
- Explained determinism guarantees explicitly
|
|
27
|
+
- Referenced real products (ByX, Frontierra)
|
|
28
|
+
|
|
29
|
+
### Unchanged
|
|
30
|
+
|
|
31
|
+
- No changes to execution or determinism
|
|
32
|
+
- No changes to protocol version (remains v1.2.0)
|
|
33
|
+
- No runtime validation or enforcement
|
|
34
|
+
- No new required files or dependencies
|
|
35
|
+
- Full backward compatibility with v1.5.x
|
|
36
|
+
- Existing sketches run unchanged
|
|
37
|
+
|
|
38
|
+
### Verification
|
|
39
|
+
|
|
40
|
+
Run `npx tsx scripts/check-determinism.ts` — must pass before release.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
7
44
|
## [1.5.1] — 2026-01-05
|
|
8
45
|
|
|
9
46
|
### Added
|
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
|
package/README.md
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
# NexArt Code Mode Runtime SDK
|
|
2
2
|
|
|
3
|
-
**Version: 1.
|
|
3
|
+
**Version: 1.6.0 (Protocol v1.2.0)**
|
|
4
4
|
|
|
5
5
|
╔══════════════════════════════════════════════════════════════════════════════╗
|
|
6
|
-
║ @nexart/codemode-sdk — Canonical
|
|
6
|
+
║ @nexart/codemode-sdk — Canonical Execution Surface ║
|
|
7
7
|
║ ║
|
|
8
|
-
║ This SDK
|
|
9
|
-
║ All implementations (NexArt, ByX, external) MUST use this SDK. ║
|
|
8
|
+
║ This SDK IS the protocol. All implementations MUST use this SDK. ║
|
|
10
9
|
║ ║
|
|
11
10
|
║ Protocol: nexart ║
|
|
12
11
|
║ Engine: codemode ║
|
|
13
|
-
║ SDK Version: 1.
|
|
12
|
+
║ SDK Version: 1.6.0 ║
|
|
14
13
|
║ Protocol Version: 1.2.0 ║
|
|
15
14
|
║ Phase: 3 ║
|
|
16
15
|
║ Enforcement: HARD ║
|
|
@@ -18,6 +17,15 @@
|
|
|
18
17
|
|
|
19
18
|
---
|
|
20
19
|
|
|
20
|
+
## Commercial Licensing
|
|
21
|
+
|
|
22
|
+
> **Commercial usage of NexArt Protocol requires a license.**
|
|
23
|
+
> **Enforcement is not active yet.**
|
|
24
|
+
|
|
25
|
+
The SDK is currently provided under the MIT License for all usage. A future version may introduce commercial licensing requirements. See [LICENSE.md](./LICENSE.md) for details.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
21
29
|
## PROTOCOL LOCK — v1.x
|
|
22
30
|
|
|
23
31
|
| Property | Value |
|
|
@@ -54,32 +62,85 @@ The answer is: "Whatever @nexart/codemode-sdk does — that is the protocol."
|
|
|
54
62
|
|
|
55
63
|
---
|
|
56
64
|
|
|
57
|
-
## What's New in v1.
|
|
65
|
+
## What's New in v1.6.0
|
|
58
66
|
|
|
59
|
-
**
|
|
67
|
+
**Licensing & Builder Identity Scaffolding (Metadata Only)**
|
|
60
68
|
|
|
61
|
-
-
|
|
69
|
+
This is a non-breaking, metadata-only release. No changes to execution or determinism.
|
|
62
70
|
|
|
63
|
-
|
|
71
|
+
### Licensing (Informational Only)
|
|
72
|
+
- Added `LICENSE.md` with draft commercial licensing terms
|
|
73
|
+
- Enforcement is NOT active — all usage currently permitted under MIT
|
|
64
74
|
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
- **
|
|
69
|
-
- **Non-rewarding** — No incentives, no tracking
|
|
75
|
+
### Builder Manifest Schema
|
|
76
|
+
- Added `builder.manifest.schema.json` for optional builder attribution
|
|
77
|
+
- Fields: `builder_id`, `project_name`, `contact`, `website`, `intended_use`
|
|
78
|
+
- This file is **optional**, **not validated**, and **not loaded at runtime**
|
|
70
79
|
|
|
71
|
-
|
|
80
|
+
### Documentation
|
|
81
|
+
- SDK positioned as "canonical execution surface"
|
|
82
|
+
- Explicit determinism guarantees documented
|
|
83
|
+
- Real product references (ByX, Frontierra)
|
|
72
84
|
|
|
73
|
-
|
|
74
|
-
import { registerBuilderManifest } from '@nexart/codemode-sdk';
|
|
85
|
+
---
|
|
75
86
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
## Determinism Guarantees
|
|
88
|
+
|
|
89
|
+
**The NexArt Code Mode SDK guarantees deterministic output.**
|
|
90
|
+
|
|
91
|
+
Given identical inputs:
|
|
92
|
+
- Same `source` code
|
|
93
|
+
- Same `seed`
|
|
94
|
+
- Same `vars` array
|
|
95
|
+
- Same `width` and `height`
|
|
96
|
+
- Same `mode`
|
|
97
|
+
|
|
98
|
+
The SDK will produce **byte-for-byte identical output** across all executions.
|
|
99
|
+
|
|
100
|
+
### What Breaks Determinism
|
|
101
|
+
|
|
102
|
+
The following actions will break determinism and are **blocked** by the SDK:
|
|
103
|
+
|
|
104
|
+
| Pattern | Reason | Enforcement |
|
|
105
|
+
|---------|--------|-------------|
|
|
106
|
+
| `Math.random()` | Unseeded randomness | BLOCKED |
|
|
107
|
+
| `Date.now()` | Time-based entropy | BLOCKED |
|
|
108
|
+
| `new Date()` | Time-based entropy | BLOCKED |
|
|
109
|
+
| `performance.now()` | Timing entropy | BLOCKED |
|
|
110
|
+
| `crypto.getRandomValues()` | Crypto randomness | BLOCKED |
|
|
111
|
+
| `fetch()` | External IO | BLOCKED |
|
|
112
|
+
| External imports | Uncontrolled code | BLOCKED |
|
|
113
|
+
|
|
114
|
+
Use `random()` (seeded) and `noise()` (seeded) for all randomness needs.
|
|
115
|
+
|
|
116
|
+
### Oracle Verification
|
|
117
|
+
|
|
118
|
+
Before any release, run the determinism check:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npx tsx scripts/check-determinism.ts
|
|
81
122
|
```
|
|
82
123
|
|
|
124
|
+
This compares output against a known oracle hash. If the hash changes without a protocol version bump, the release is invalid.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Products Using This SDK
|
|
129
|
+
|
|
130
|
+
- **NexArt**: Primary generative art platform
|
|
131
|
+
- **ByX**: Curated collection system
|
|
132
|
+
- **Frontierra**: External builder integration
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## v1.5.1
|
|
137
|
+
|
|
138
|
+
**Builder Manifest — Passive Attribution (Write-Only)**
|
|
139
|
+
|
|
140
|
+
- `registerBuilderManifest(manifest?)` — Declare builder identity for future attribution
|
|
141
|
+
|
|
142
|
+
The Builder Manifest is a declaration of intent, not a capability. Write-only, optional, non-enforced.
|
|
143
|
+
|
|
83
144
|
---
|
|
84
145
|
|
|
85
146
|
## v1.4.0 (Protocol v1.2.0)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://nexart.art/schemas/builder.manifest.json",
|
|
4
|
+
"title": "NexArt Builder Manifest",
|
|
5
|
+
"description": "Optional metadata file for builder attribution. NOT validated, NOT required, NOT enforced.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"protocol": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"const": "nexart",
|
|
11
|
+
"description": "Protocol identifier (must be 'nexart')"
|
|
12
|
+
},
|
|
13
|
+
"manifest_version": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "Version of this manifest schema",
|
|
16
|
+
"default": "1.0"
|
|
17
|
+
},
|
|
18
|
+
"builder_id": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "Unique identifier for the builder (self-assigned)"
|
|
21
|
+
},
|
|
22
|
+
"project_name": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "Name of the project or application"
|
|
25
|
+
},
|
|
26
|
+
"description": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"description": "Brief description of the project"
|
|
29
|
+
},
|
|
30
|
+
"contact": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"description": "Contact email or handle"
|
|
33
|
+
},
|
|
34
|
+
"website": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"format": "uri",
|
|
37
|
+
"description": "Project website URL"
|
|
38
|
+
},
|
|
39
|
+
"intended_use": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"enum": ["art", "game", "research", "commercial", "education", "other"],
|
|
42
|
+
"description": "Primary intended use case"
|
|
43
|
+
},
|
|
44
|
+
"sdk_version": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"description": "Version of @nexart/codemode-sdk being used"
|
|
47
|
+
},
|
|
48
|
+
"features": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"description": "Optional feature flags",
|
|
51
|
+
"additionalProperties": {
|
|
52
|
+
"type": "boolean"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"metadata": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"description": "Arbitrary additional metadata",
|
|
58
|
+
"additionalProperties": true
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"additionalProperties": true
|
|
62
|
+
}
|
package/dist/builder-manifest.js
CHANGED
package/dist/execute.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EAMtB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EAMtB,MAAM,SAAS,CAAC;AAuNjB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,qBAAqB,CAAC,CAmChC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAuCpH"}
|
package/dist/execute.js
CHANGED
|
@@ -143,7 +143,8 @@ async function executeStatic(input, vars) {
|
|
|
143
143
|
vars: vars,
|
|
144
144
|
onComplete: (result) => {
|
|
145
145
|
resolve({
|
|
146
|
-
image: result.blob,
|
|
146
|
+
image: 'blob' in result ? result.blob : undefined,
|
|
147
|
+
frames: 'imageData' in result ? [result.imageData] : undefined,
|
|
147
148
|
metadata: createMetadata(input, vars),
|
|
148
149
|
});
|
|
149
150
|
},
|
|
@@ -174,7 +175,7 @@ async function executeLoop(input, vars) {
|
|
|
174
175
|
vars: vars,
|
|
175
176
|
onComplete: (result) => {
|
|
176
177
|
resolve({
|
|
177
|
-
video: result.blob,
|
|
178
|
+
video: 'blob' in result && result.type === 'video' ? result.blob : undefined,
|
|
178
179
|
metadata: createMetadata(input, vars),
|
|
179
180
|
});
|
|
180
181
|
},
|
|
@@ -214,7 +215,7 @@ export async function executeCodeMode(input) {
|
|
|
214
215
|
// Normalize VAR values
|
|
215
216
|
const vars = normalizeVars(input.vars);
|
|
216
217
|
// ╔═══════════════════════════════════════════════════════════════════════╗
|
|
217
|
-
// ║ BUILDER MANIFEST CONTEXT (v1.
|
|
218
|
+
// ║ BUILDER MANIFEST CONTEXT (v1.6.0) ║
|
|
218
219
|
// ║ ║
|
|
219
220
|
// ║ Internal context for builder attribution. ║
|
|
220
221
|
// ║ This is NOT exposed to sketch code, NOT serialized, NOT logged. ║
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NexArt Code Mode SDK - Execution Sandbox
|
|
3
|
+
* Version: 1.6.0 (Protocol v1.2.0)
|
|
4
|
+
*
|
|
5
|
+
* ╔══════════════════════════════════════════════════════════════════════════╗
|
|
6
|
+
* ║ EXECUTION BOUNDARY — HARD ENFORCEMENT ║
|
|
7
|
+
* ║ ║
|
|
8
|
+
* ║ This module enforces determinism by blocking all external entropy ║
|
|
9
|
+
* ║ sources at RUNTIME, not just via static pattern scanning. ║
|
|
10
|
+
* ║ ║
|
|
11
|
+
* ║ Blocked APIs (throw [Code Mode Protocol Error]): ║
|
|
12
|
+
* ║ - Date, Date.now, Date.parse, new Date() ║
|
|
13
|
+
* ║ - performance, performance.now ║
|
|
14
|
+
* ║ - process (Node.js) ║
|
|
15
|
+
* ║ - navigator ║
|
|
16
|
+
* ║ - globalThis ║
|
|
17
|
+
* ║ - crypto.getRandomValues ║
|
|
18
|
+
* ║ - Math.random (use seeded random() instead) ║
|
|
19
|
+
* ║ - setTimeout, setInterval, requestAnimationFrame ║
|
|
20
|
+
* ║ - fetch, XMLHttpRequest ║
|
|
21
|
+
* ║ - document, window ║
|
|
22
|
+
* ║ - import, require ║
|
|
23
|
+
* ║ ║
|
|
24
|
+
* ║ All blocked symbols throw immediately on access — no silent undefined. ║
|
|
25
|
+
* ╚══════════════════════════════════════════════════════════════════════════╝
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Forbidden APIs - these are injected into the execution scope to override globals
|
|
29
|
+
*/
|
|
30
|
+
export declare const FORBIDDEN_APIS: {
|
|
31
|
+
readonly Date: (...args: any[]) => never;
|
|
32
|
+
readonly performance: object;
|
|
33
|
+
readonly process: object;
|
|
34
|
+
readonly navigator: object;
|
|
35
|
+
readonly globalThis: object;
|
|
36
|
+
readonly crypto: object;
|
|
37
|
+
readonly setTimeout: (...args: any[]) => never;
|
|
38
|
+
readonly setInterval: (...args: any[]) => never;
|
|
39
|
+
readonly clearTimeout: (...args: any[]) => never;
|
|
40
|
+
readonly clearInterval: (...args: any[]) => never;
|
|
41
|
+
readonly requestAnimationFrame: (...args: any[]) => never;
|
|
42
|
+
readonly cancelAnimationFrame: (...args: any[]) => never;
|
|
43
|
+
readonly fetch: (...args: any[]) => never;
|
|
44
|
+
readonly XMLHttpRequest: (...args: any[]) => never;
|
|
45
|
+
readonly WebSocket: (...args: any[]) => never;
|
|
46
|
+
readonly document: object;
|
|
47
|
+
readonly window: object;
|
|
48
|
+
readonly self: object;
|
|
49
|
+
readonly top: object;
|
|
50
|
+
readonly parent: object;
|
|
51
|
+
readonly frames: object;
|
|
52
|
+
readonly location: object;
|
|
53
|
+
readonly history: object;
|
|
54
|
+
readonly localStorage: object;
|
|
55
|
+
readonly sessionStorage: object;
|
|
56
|
+
readonly indexedDB: object;
|
|
57
|
+
readonly caches: object;
|
|
58
|
+
readonly Notification: (...args: any[]) => never;
|
|
59
|
+
readonly Worker: (...args: any[]) => never;
|
|
60
|
+
readonly SharedWorker: (...args: any[]) => never;
|
|
61
|
+
readonly ServiceWorker: object;
|
|
62
|
+
readonly Blob: (...args: any[]) => never;
|
|
63
|
+
readonly File: (...args: any[]) => never;
|
|
64
|
+
readonly FileReader: (...args: any[]) => never;
|
|
65
|
+
readonly URL: (...args: any[]) => never;
|
|
66
|
+
readonly URLSearchParams: (...args: any[]) => never;
|
|
67
|
+
readonly Headers: (...args: any[]) => never;
|
|
68
|
+
readonly Request: (...args: any[]) => never;
|
|
69
|
+
readonly Response: (...args: any[]) => never;
|
|
70
|
+
readonly EventSource: (...args: any[]) => never;
|
|
71
|
+
readonly Image: (...args: any[]) => never;
|
|
72
|
+
readonly Audio: (...args: any[]) => never;
|
|
73
|
+
readonly Video: (...args: any[]) => never;
|
|
74
|
+
readonly eval: (...args: any[]) => never;
|
|
75
|
+
readonly Function: (...args: any[]) => never;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Create a safe Math object with random() blocked
|
|
79
|
+
*/
|
|
80
|
+
export declare function createSafeMath(): typeof Math;
|
|
81
|
+
/**
|
|
82
|
+
* List of all forbidden API names for documentation
|
|
83
|
+
*/
|
|
84
|
+
export declare const FORBIDDEN_API_NAMES: string[];
|
|
85
|
+
/**
|
|
86
|
+
* Build the complete sandbox context for sketch execution.
|
|
87
|
+
* This includes the p5 runtime plus all forbidden API stubs.
|
|
88
|
+
*/
|
|
89
|
+
export declare function buildSandboxContext(p5Runtime: Record<string, any>): Record<string, any>;
|
|
90
|
+
/**
|
|
91
|
+
* Create a sandboxed function that executes user code with blocked globals.
|
|
92
|
+
*
|
|
93
|
+
* The function is constructed with:
|
|
94
|
+
* 1. All forbidden APIs as explicit parameters (override globals)
|
|
95
|
+
* 2. The p5 runtime as explicit parameters
|
|
96
|
+
* 3. A `with(context)` wrapper for additional safety
|
|
97
|
+
*/
|
|
98
|
+
export declare function createSandboxedExecutor(code: string, additionalParams?: string[]): Function;
|
|
99
|
+
/**
|
|
100
|
+
* Execute user code in a sandboxed environment.
|
|
101
|
+
*
|
|
102
|
+
* @param code - The user sketch code to execute
|
|
103
|
+
* @param p5Runtime - The p5-like runtime object
|
|
104
|
+
* @param additionalContext - Additional context variables (frameCount, t, etc.)
|
|
105
|
+
*/
|
|
106
|
+
export declare function executeSandboxed(code: string, p5Runtime: Record<string, any>, additionalContext?: Record<string, any>): void;
|
|
107
|
+
//# sourceMappingURL=execution-sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-sandbox.d.ts","sourceRoot":"","sources":["../execution-sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAyDH;;GAEG;AACH,eAAO,MAAM,cAAc;6BAvD2B,GAAG,EAAE,KAAK,KAAK;;;;;;mCAAf,GAAG,EAAE,KAAK,KAAK;oCAAf,GAAG,EAAE,KAAK,KAAK;qCAAf,GAAG,EAAE,KAAK,KAAK;sCAAf,GAAG,EAAE,KAAK,KAAK;8CAAf,GAAG,EAAE,KAAK,KAAK;6CAAf,GAAG,EAAE,KAAK,KAAK;8BAAf,GAAG,EAAE,KAAK,KAAK;uCAAf,GAAG,EAAE,KAAK,KAAK;kCAAf,GAAG,EAAE,KAAK,KAAK;;;;;;;;;;;;;qCAAf,GAAG,EAAE,KAAK,KAAK;+BAAf,GAAG,EAAE,KAAK,KAAK;qCAAf,GAAG,EAAE,KAAK,KAAK;;6BAAf,GAAG,EAAE,KAAK,KAAK;6BAAf,GAAG,EAAE,KAAK,KAAK;mCAAf,GAAG,EAAE,KAAK,KAAK;4BAAf,GAAG,EAAE,KAAK,KAAK;wCAAf,GAAG,EAAE,KAAK,KAAK;gCAAf,GAAG,EAAE,KAAK,KAAK;gCAAf,GAAG,EAAE,KAAK,KAAK;iCAAf,GAAG,EAAE,KAAK,KAAK;oCAAf,GAAG,EAAE,KAAK,KAAK;8BAAf,GAAG,EAAE,KAAK,KAAK;8BAAf,GAAG,EAAE,KAAK,KAAK;8BAAf,GAAG,EAAE,KAAK,KAAK;6BAAf,GAAG,EAAE,KAAK,KAAK;iCAAf,GAAG,EAAE,KAAK,KAAK;CAqG3D,CAAC;AAEX;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,IAAI,CAU5C;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,UAA8B,CAAC;AAE/D;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAavF;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,gBAAgB,GAAE,MAAM,EAAO,GAC9B,QAAQ,CAiBV;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC9B,iBAAiB,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAC1C,IAAI,CAsBN"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NexArt Code Mode SDK - Execution Sandbox
|
|
3
|
+
* Version: 1.6.0 (Protocol v1.2.0)
|
|
4
|
+
*
|
|
5
|
+
* ╔══════════════════════════════════════════════════════════════════════════╗
|
|
6
|
+
* ║ EXECUTION BOUNDARY — HARD ENFORCEMENT ║
|
|
7
|
+
* ║ ║
|
|
8
|
+
* ║ This module enforces determinism by blocking all external entropy ║
|
|
9
|
+
* ║ sources at RUNTIME, not just via static pattern scanning. ║
|
|
10
|
+
* ║ ║
|
|
11
|
+
* ║ Blocked APIs (throw [Code Mode Protocol Error]): ║
|
|
12
|
+
* ║ - Date, Date.now, Date.parse, new Date() ║
|
|
13
|
+
* ║ - performance, performance.now ║
|
|
14
|
+
* ║ - process (Node.js) ║
|
|
15
|
+
* ║ - navigator ║
|
|
16
|
+
* ║ - globalThis ║
|
|
17
|
+
* ║ - crypto.getRandomValues ║
|
|
18
|
+
* ║ - Math.random (use seeded random() instead) ║
|
|
19
|
+
* ║ - setTimeout, setInterval, requestAnimationFrame ║
|
|
20
|
+
* ║ - fetch, XMLHttpRequest ║
|
|
21
|
+
* ║ - document, window ║
|
|
22
|
+
* ║ - import, require ║
|
|
23
|
+
* ║ ║
|
|
24
|
+
* ║ All blocked symbols throw immediately on access — no silent undefined. ║
|
|
25
|
+
* ╚══════════════════════════════════════════════════════════════════════════╝
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Create a throwing stub for a forbidden API
|
|
29
|
+
*/
|
|
30
|
+
function createForbiddenStub(name) {
|
|
31
|
+
const stub = function () {
|
|
32
|
+
throw new Error(`[Code Mode Protocol Error] Forbidden API: ${name}`);
|
|
33
|
+
};
|
|
34
|
+
return new Proxy(stub, {
|
|
35
|
+
get(_target, prop) {
|
|
36
|
+
if (prop === Symbol.toPrimitive || prop === 'toString' || prop === 'valueOf') {
|
|
37
|
+
return () => { throw new Error(`[Code Mode Protocol Error] Forbidden API: ${name}`); };
|
|
38
|
+
}
|
|
39
|
+
throw new Error(`[Code Mode Protocol Error] Forbidden API: ${name}.${String(prop)}`);
|
|
40
|
+
},
|
|
41
|
+
apply() {
|
|
42
|
+
throw new Error(`[Code Mode Protocol Error] Forbidden API: ${name}()`);
|
|
43
|
+
},
|
|
44
|
+
construct() {
|
|
45
|
+
throw new Error(`[Code Mode Protocol Error] Forbidden API: new ${name}()`);
|
|
46
|
+
},
|
|
47
|
+
set() {
|
|
48
|
+
throw new Error(`[Code Mode Protocol Error] Forbidden API: ${name} (assignment blocked)`);
|
|
49
|
+
},
|
|
50
|
+
has() {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create a frozen object that throws on any property access
|
|
57
|
+
*/
|
|
58
|
+
function createForbiddenObject(name) {
|
|
59
|
+
return new Proxy({}, {
|
|
60
|
+
get(_target, prop) {
|
|
61
|
+
if (prop === Symbol.toPrimitive || prop === 'toString' || prop === 'valueOf') {
|
|
62
|
+
return () => { throw new Error(`[Code Mode Protocol Error] Forbidden API: ${name}`); };
|
|
63
|
+
}
|
|
64
|
+
throw new Error(`[Code Mode Protocol Error] Forbidden API: ${name}.${String(prop)}`);
|
|
65
|
+
},
|
|
66
|
+
set() {
|
|
67
|
+
throw new Error(`[Code Mode Protocol Error] Forbidden API: ${name} (assignment blocked)`);
|
|
68
|
+
},
|
|
69
|
+
has() {
|
|
70
|
+
return true;
|
|
71
|
+
},
|
|
72
|
+
apply() {
|
|
73
|
+
throw new Error(`[Code Mode Protocol Error] Forbidden API: ${name}()`);
|
|
74
|
+
},
|
|
75
|
+
construct() {
|
|
76
|
+
throw new Error(`[Code Mode Protocol Error] Forbidden API: new ${name}()`);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Forbidden APIs - these are injected into the execution scope to override globals
|
|
82
|
+
*/
|
|
83
|
+
export const FORBIDDEN_APIS = {
|
|
84
|
+
Date: createForbiddenStub('Date'),
|
|
85
|
+
performance: createForbiddenObject('performance'),
|
|
86
|
+
process: createForbiddenObject('process'),
|
|
87
|
+
navigator: createForbiddenObject('navigator'),
|
|
88
|
+
globalThis: createForbiddenObject('globalThis'),
|
|
89
|
+
crypto: createForbiddenObject('crypto'),
|
|
90
|
+
setTimeout: createForbiddenStub('setTimeout'),
|
|
91
|
+
setInterval: createForbiddenStub('setInterval'),
|
|
92
|
+
clearTimeout: createForbiddenStub('clearTimeout'),
|
|
93
|
+
clearInterval: createForbiddenStub('clearInterval'),
|
|
94
|
+
requestAnimationFrame: createForbiddenStub('requestAnimationFrame'),
|
|
95
|
+
cancelAnimationFrame: createForbiddenStub('cancelAnimationFrame'),
|
|
96
|
+
fetch: createForbiddenStub('fetch'),
|
|
97
|
+
XMLHttpRequest: createForbiddenStub('XMLHttpRequest'),
|
|
98
|
+
WebSocket: createForbiddenStub('WebSocket'),
|
|
99
|
+
document: createForbiddenObject('document'),
|
|
100
|
+
window: createForbiddenObject('window'),
|
|
101
|
+
self: createForbiddenObject('self'),
|
|
102
|
+
top: createForbiddenObject('top'),
|
|
103
|
+
parent: createForbiddenObject('parent'),
|
|
104
|
+
frames: createForbiddenObject('frames'),
|
|
105
|
+
location: createForbiddenObject('location'),
|
|
106
|
+
history: createForbiddenObject('history'),
|
|
107
|
+
localStorage: createForbiddenObject('localStorage'),
|
|
108
|
+
sessionStorage: createForbiddenObject('sessionStorage'),
|
|
109
|
+
indexedDB: createForbiddenObject('indexedDB'),
|
|
110
|
+
caches: createForbiddenObject('caches'),
|
|
111
|
+
Notification: createForbiddenStub('Notification'),
|
|
112
|
+
Worker: createForbiddenStub('Worker'),
|
|
113
|
+
SharedWorker: createForbiddenStub('SharedWorker'),
|
|
114
|
+
ServiceWorker: createForbiddenObject('ServiceWorker'),
|
|
115
|
+
Blob: createForbiddenStub('Blob'),
|
|
116
|
+
File: createForbiddenStub('File'),
|
|
117
|
+
FileReader: createForbiddenStub('FileReader'),
|
|
118
|
+
URL: createForbiddenStub('URL'),
|
|
119
|
+
URLSearchParams: createForbiddenStub('URLSearchParams'),
|
|
120
|
+
Headers: createForbiddenStub('Headers'),
|
|
121
|
+
Request: createForbiddenStub('Request'),
|
|
122
|
+
Response: createForbiddenStub('Response'),
|
|
123
|
+
EventSource: createForbiddenStub('EventSource'),
|
|
124
|
+
Image: createForbiddenStub('Image'),
|
|
125
|
+
Audio: createForbiddenStub('Audio'),
|
|
126
|
+
Video: createForbiddenStub('Video'),
|
|
127
|
+
eval: createForbiddenStub('eval'),
|
|
128
|
+
Function: createForbiddenStub('Function'),
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Create a safe Math object with random() blocked
|
|
132
|
+
*/
|
|
133
|
+
export function createSafeMath() {
|
|
134
|
+
const safeMath = Object.create(Math);
|
|
135
|
+
Object.defineProperty(safeMath, 'random', {
|
|
136
|
+
get() {
|
|
137
|
+
throw new Error('[Code Mode Protocol Error] Forbidden API: Math.random() — use random() instead (seeded)');
|
|
138
|
+
},
|
|
139
|
+
configurable: false,
|
|
140
|
+
enumerable: true
|
|
141
|
+
});
|
|
142
|
+
return Object.freeze(safeMath);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* List of all forbidden API names for documentation
|
|
146
|
+
*/
|
|
147
|
+
export const FORBIDDEN_API_NAMES = Object.keys(FORBIDDEN_APIS);
|
|
148
|
+
/**
|
|
149
|
+
* Build the complete sandbox context for sketch execution.
|
|
150
|
+
* This includes the p5 runtime plus all forbidden API stubs.
|
|
151
|
+
*/
|
|
152
|
+
export function buildSandboxContext(p5Runtime) {
|
|
153
|
+
const safeMath = createSafeMath();
|
|
154
|
+
const context = {
|
|
155
|
+
...FORBIDDEN_APIS,
|
|
156
|
+
Math: safeMath,
|
|
157
|
+
};
|
|
158
|
+
for (const key of Object.keys(p5Runtime)) {
|
|
159
|
+
context[key] = p5Runtime[key];
|
|
160
|
+
}
|
|
161
|
+
return context;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Create a sandboxed function that executes user code with blocked globals.
|
|
165
|
+
*
|
|
166
|
+
* The function is constructed with:
|
|
167
|
+
* 1. All forbidden APIs as explicit parameters (override globals)
|
|
168
|
+
* 2. The p5 runtime as explicit parameters
|
|
169
|
+
* 3. A `with(context)` wrapper for additional safety
|
|
170
|
+
*/
|
|
171
|
+
export function createSandboxedExecutor(code, additionalParams = []) {
|
|
172
|
+
const forbiddenParamNames = Object.keys(FORBIDDEN_APIS);
|
|
173
|
+
const allParams = [
|
|
174
|
+
'context',
|
|
175
|
+
'Math',
|
|
176
|
+
...forbiddenParamNames,
|
|
177
|
+
...additionalParams
|
|
178
|
+
];
|
|
179
|
+
const wrappedCode = `
|
|
180
|
+
"use strict";
|
|
181
|
+
with(context) {
|
|
182
|
+
${code}
|
|
183
|
+
}
|
|
184
|
+
`;
|
|
185
|
+
return new Function(...allParams, wrappedCode);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Execute user code in a sandboxed environment.
|
|
189
|
+
*
|
|
190
|
+
* @param code - The user sketch code to execute
|
|
191
|
+
* @param p5Runtime - The p5-like runtime object
|
|
192
|
+
* @param additionalContext - Additional context variables (frameCount, t, etc.)
|
|
193
|
+
*/
|
|
194
|
+
export function executeSandboxed(code, p5Runtime, additionalContext = {}) {
|
|
195
|
+
const safeMath = createSafeMath();
|
|
196
|
+
const fullContext = {
|
|
197
|
+
...p5Runtime,
|
|
198
|
+
...additionalContext,
|
|
199
|
+
Math: safeMath,
|
|
200
|
+
...FORBIDDEN_APIS,
|
|
201
|
+
};
|
|
202
|
+
const forbiddenValues = Object.keys(FORBIDDEN_APIS).map(key => FORBIDDEN_APIS[key]);
|
|
203
|
+
const additionalParamNames = Object.keys(additionalContext);
|
|
204
|
+
const additionalValues = Object.values(additionalContext);
|
|
205
|
+
const executor = createSandboxedExecutor(code, additionalParamNames);
|
|
206
|
+
executor(fullContext, safeMath, ...forbiddenValues, ...additionalValues);
|
|
207
|
+
}
|
package/dist/loop-engine.d.ts
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Determinism Guarantee:
|
|
14
14
|
* Same code + same seed + same VARs = identical frame sequence
|
|
15
|
+
*
|
|
16
|
+
* Security:
|
|
17
|
+
* All external entropy sources are blocked at runtime via execution sandbox.
|
|
15
18
|
*/
|
|
16
19
|
import type { EngineConfig, RunOptions } from './types';
|
|
17
20
|
export declare function cancelLoopMode(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop-engine.d.ts","sourceRoot":"","sources":["../loop-engine.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loop-engine.d.ts","sourceRoot":"","sources":["../loop-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAA+B,MAAM,SAAS,CAAC;AAOrF,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CA+Mf"}
|
package/dist/loop-engine.js
CHANGED
|
@@ -12,9 +12,13 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Determinism Guarantee:
|
|
14
14
|
* Same code + same seed + same VARs = identical frame sequence
|
|
15
|
+
*
|
|
16
|
+
* Security:
|
|
17
|
+
* All external entropy sources are blocked at runtime via execution sandbox.
|
|
15
18
|
*/
|
|
16
19
|
import { DEFAULT_CONFIG } from './types';
|
|
17
20
|
import { createP5Runtime, injectProtocolVariables } from './p5-runtime';
|
|
21
|
+
import { FORBIDDEN_APIS, createSafeMath } from './execution-sandbox';
|
|
18
22
|
let isCancelled = false;
|
|
19
23
|
export function cancelLoopMode() {
|
|
20
24
|
isCancelled = true;
|
|
@@ -72,16 +76,22 @@ export async function runLoopMode(config, options) {
|
|
|
72
76
|
}
|
|
73
77
|
// Inject totalFrames into runtime
|
|
74
78
|
p.totalFrames = totalFrames;
|
|
75
|
-
// Create
|
|
76
|
-
|
|
77
|
-
const
|
|
79
|
+
// Create sandboxed execution context
|
|
80
|
+
// All forbidden APIs are injected as parameters to override globals
|
|
81
|
+
const safeMath = createSafeMath();
|
|
82
|
+
const forbiddenKeys = Object.keys(FORBIDDEN_APIS);
|
|
83
|
+
// Create wrapped functions with p5 context, time variables, VAR, totalFrames, and blocked globals
|
|
84
|
+
const wrappedSetup = new Function('p', 'frameCount', 't', 'time', 'tGlobal', 'VAR', 'totalFrames', 'Math', ...forbiddenKeys, `with(p) { ${setupCode} }`);
|
|
85
|
+
const wrappedDraw = new Function('p', 'frameCount', 't', 'time', 'tGlobal', 'VAR', 'totalFrames', 'Math', ...forbiddenKeys, `with(p) { ${drawCode} }`);
|
|
86
|
+
// Get forbidden values array for execution
|
|
87
|
+
const forbiddenValues = forbiddenKeys.map(k => FORBIDDEN_APIS[k]);
|
|
78
88
|
onProgress?.({
|
|
79
89
|
phase: 'setup',
|
|
80
90
|
percent: 10,
|
|
81
91
|
message: 'Executing setup()...',
|
|
82
92
|
});
|
|
83
|
-
// Execute setup() once with time = 0, VAR, and
|
|
84
|
-
wrappedSetup(p, 0, 0, 0, 0, p.VAR, totalFrames);
|
|
93
|
+
// Execute setup() once with time = 0, VAR, totalFrames, and sandboxed context
|
|
94
|
+
wrappedSetup(p, 0, 0, 0, 0, p.VAR, totalFrames, safeMath, ...forbiddenValues);
|
|
85
95
|
// Capture frames
|
|
86
96
|
const frames = [];
|
|
87
97
|
onProgress?.({
|
|
@@ -108,8 +118,8 @@ export async function runLoopMode(config, options) {
|
|
|
108
118
|
// 2. Reset blend mode to NORMAL (Protocol v1.1 requirement)
|
|
109
119
|
// Prevents blend mode state from persisting across frames
|
|
110
120
|
p.blendMode('NORMAL');
|
|
111
|
-
// Execute draw() with time variables, VAR, and
|
|
112
|
-
wrappedDraw(p, frame, t, time, t, p.VAR, totalFrames);
|
|
121
|
+
// Execute draw() with time variables, VAR, totalFrames, and sandboxed context
|
|
122
|
+
wrappedDraw(p, frame, t, time, t, p.VAR, totalFrames, safeMath, ...forbiddenValues);
|
|
113
123
|
// Capture frame as PNG blob
|
|
114
124
|
const blob = await new Promise((resolve, reject) => {
|
|
115
125
|
canvas.toBlob((b) => b ? resolve(b) : reject(new Error(`Failed to capture frame ${frame}`)), 'image/png');
|
package/dist/p5-runtime.d.ts
CHANGED
|
@@ -49,7 +49,8 @@ export interface P5Runtime {
|
|
|
49
49
|
export interface P5RuntimeConfig {
|
|
50
50
|
seed?: number;
|
|
51
51
|
}
|
|
52
|
-
|
|
52
|
+
type RuntimeCanvas = HTMLCanvasElement;
|
|
53
|
+
export declare function createP5Runtime(canvas: RuntimeCanvas, width: number, height: number, config?: P5RuntimeConfig): P5Runtime;
|
|
53
54
|
export declare function injectTimeVariables(p: P5Runtime, time: TimeVariables): void;
|
|
54
55
|
/**
|
|
55
56
|
* VAR Protocol Constants (Phase 1 — Protocol v1.0.0)
|
|
@@ -70,4 +71,5 @@ export declare const VAR_MAX = 100;
|
|
|
70
71
|
*/
|
|
71
72
|
export declare function createProtocolVAR(vars?: number[]): readonly number[];
|
|
72
73
|
export declare function injectProtocolVariables(p: P5Runtime, vars?: number[]): void;
|
|
74
|
+
export {};
|
|
73
75
|
//# sourceMappingURL=p5-runtime.d.ts.map
|
package/dist/p5-runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"p5-runtime.d.ts","sourceRoot":"","sources":["../p5-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,UAAU,CAAC;AAClD,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,qBAAqB,EAAG,MAAe,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAmED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"p5-runtime.d.ts","sourceRoot":"","sources":["../p5-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,UAAU,CAAC;AAClD,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,qBAAqB,EAAG,MAAe,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAmED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,KAAK,aAAa,GAAG,iBAAiB,CAAC;AAEvC,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,eAAe,GACvB,SAAS,CAs8BX;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAM3E;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS,KAAK,CAAC;AAC5B,eAAO,MAAM,OAAO,IAAI,CAAC;AACzB,eAAO,MAAM,OAAO,MAAM,CAAC;AAE3B;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,CAmCpE;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAE3E"}
|
package/dist/p5-runtime.js
CHANGED
|
@@ -93,6 +93,8 @@ function createSeededNoise(seed = 0) {
|
|
|
93
93
|
}
|
|
94
94
|
export function createP5Runtime(canvas, width, height, config) {
|
|
95
95
|
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
|
96
|
+
if (!ctx)
|
|
97
|
+
throw new Error('Failed to get 2D context');
|
|
96
98
|
let currentFill = 'rgba(255, 255, 255, 1)';
|
|
97
99
|
let currentStroke = 'rgba(0, 0, 0, 1)';
|
|
98
100
|
let strokeEnabled = true;
|
package/dist/static-engine.d.ts
CHANGED
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Determinism Guarantee:
|
|
9
9
|
* Same code + same seed + same VARs = identical PNG output
|
|
10
|
+
*
|
|
11
|
+
* Security:
|
|
12
|
+
* All external entropy sources are blocked at runtime via execution sandbox.
|
|
13
|
+
*
|
|
14
|
+
* Oracle Support:
|
|
15
|
+
* When returnImageData is true, returns raw ImageData for determinism hashing.
|
|
16
|
+
* Works in both browser (HTMLCanvasElement) and Node (canvas package) environments.
|
|
10
17
|
*/
|
|
11
18
|
import type { EngineConfig, RunOptions } from './types';
|
|
12
19
|
export declare function runStaticMode(config: EngineConfig, options: RunOptions): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-engine.d.ts","sourceRoot":"","sources":["../static-engine.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"static-engine.d.ts","sourceRoot":"","sources":["../static-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAgB,MAAM,SAAS,CAAC;AAoCtE,wBAAsB,aAAa,CACjC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CA6Hf"}
|
package/dist/static-engine.js
CHANGED
|
@@ -7,11 +7,44 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Determinism Guarantee:
|
|
9
9
|
* Same code + same seed + same VARs = identical PNG output
|
|
10
|
+
*
|
|
11
|
+
* Security:
|
|
12
|
+
* All external entropy sources are blocked at runtime via execution sandbox.
|
|
13
|
+
*
|
|
14
|
+
* Oracle Support:
|
|
15
|
+
* When returnImageData is true, returns raw ImageData for determinism hashing.
|
|
16
|
+
* Works in both browser (HTMLCanvasElement) and Node (canvas package) environments.
|
|
10
17
|
*/
|
|
18
|
+
import { createRequire } from 'module';
|
|
11
19
|
import { DEFAULT_CONFIG } from './types';
|
|
12
20
|
import { createP5Runtime, injectTimeVariables, injectProtocolVariables } from './p5-runtime';
|
|
21
|
+
import { FORBIDDEN_APIS, createSafeMath } from './execution-sandbox';
|
|
22
|
+
const require = createRequire(import.meta.url);
|
|
23
|
+
/**
|
|
24
|
+
* Create a runtime canvas that works in both browser and Node environments.
|
|
25
|
+
* Browser: uses HTMLCanvasElement
|
|
26
|
+
* Node/Headless: uses `canvas` npm package
|
|
27
|
+
*/
|
|
28
|
+
function createRuntimeCanvas(width, height) {
|
|
29
|
+
// Browser environment
|
|
30
|
+
if (typeof document !== 'undefined' && typeof document.createElement === 'function') {
|
|
31
|
+
const canvas = document.createElement('canvas');
|
|
32
|
+
canvas.width = width;
|
|
33
|
+
canvas.height = height;
|
|
34
|
+
return canvas;
|
|
35
|
+
}
|
|
36
|
+
// Node / headless environment (oracle, CI)
|
|
37
|
+
try {
|
|
38
|
+
const { createCanvas } = require('canvas');
|
|
39
|
+
return createCanvas(width, height);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
throw new Error('[Code Mode Protocol Error] Headless canvas unavailable. ' +
|
|
43
|
+
'Install `canvas` for oracle execution.');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
13
46
|
export async function runStaticMode(config, options) {
|
|
14
|
-
const { code, seed, vars, onPreview, onProgress, onComplete, onError } = options;
|
|
47
|
+
const { code, seed, vars, onPreview, onProgress, onComplete, onError, returnImageData } = options;
|
|
15
48
|
const width = config.width ?? DEFAULT_CONFIG.width;
|
|
16
49
|
const height = config.height ?? DEFAULT_CONFIG.height;
|
|
17
50
|
try {
|
|
@@ -20,10 +53,8 @@ export async function runStaticMode(config, options) {
|
|
|
20
53
|
percent: 0,
|
|
21
54
|
message: 'Initializing canvas...',
|
|
22
55
|
});
|
|
23
|
-
// Create
|
|
24
|
-
const canvas =
|
|
25
|
-
canvas.width = width;
|
|
26
|
-
canvas.height = height;
|
|
56
|
+
// Create runtime canvas (browser or Node)
|
|
57
|
+
const canvas = createRuntimeCanvas(width, height);
|
|
27
58
|
// Create p5 runtime with optional seed for determinism
|
|
28
59
|
const p = createP5Runtime(canvas, width, height, { seed });
|
|
29
60
|
// Inject time variables (static = frame 0, t = 0, totalFrames = 1)
|
|
@@ -56,18 +87,43 @@ export async function runStaticMode(config, options) {
|
|
|
56
87
|
percent: 30,
|
|
57
88
|
message: 'Executing setup()...',
|
|
58
89
|
});
|
|
59
|
-
// Create
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
90
|
+
// Create sandboxed execution context
|
|
91
|
+
// All forbidden APIs are injected as parameters to override globals
|
|
92
|
+
const safeMath = createSafeMath();
|
|
93
|
+
const forbiddenKeys = Object.keys(FORBIDDEN_APIS);
|
|
94
|
+
// Create wrapped setup function with p5 context, VAR, and blocked globals
|
|
95
|
+
const wrappedSetup = new Function('p', 'frameCount', 't', 'time', 'tGlobal', 'VAR', 'Math', ...forbiddenKeys, `with(p) { ${setupCode} }`);
|
|
96
|
+
// Execute setup() only with sandboxed context
|
|
97
|
+
const forbiddenValues = forbiddenKeys.map(k => FORBIDDEN_APIS[k]);
|
|
98
|
+
wrappedSetup(p, 0, 0, 0, 0, p.VAR, safeMath, ...forbiddenValues);
|
|
63
99
|
// Provide preview callback
|
|
64
100
|
onPreview?.(canvas);
|
|
65
101
|
onProgress?.({
|
|
66
102
|
phase: 'encoding',
|
|
67
103
|
percent: 70,
|
|
68
|
-
message: 'Capturing PNG...',
|
|
104
|
+
message: returnImageData ? 'Capturing ImageData...' : 'Capturing PNG...',
|
|
69
105
|
});
|
|
70
|
-
//
|
|
106
|
+
// Get 2D context for pixel access
|
|
107
|
+
const ctx = canvas.getContext('2d');
|
|
108
|
+
if (!ctx) {
|
|
109
|
+
throw new Error('Failed to acquire 2D context');
|
|
110
|
+
}
|
|
111
|
+
// Always capture pixel data first
|
|
112
|
+
const imageData = ctx.getImageData(0, 0, width, height);
|
|
113
|
+
// ORACLE / NODE PATH — MUST NOT TOUCH toBlob
|
|
114
|
+
if (returnImageData) {
|
|
115
|
+
onProgress?.({
|
|
116
|
+
phase: 'complete',
|
|
117
|
+
percent: 100,
|
|
118
|
+
message: 'Complete',
|
|
119
|
+
});
|
|
120
|
+
onComplete({
|
|
121
|
+
type: 'image',
|
|
122
|
+
imageData,
|
|
123
|
+
});
|
|
124
|
+
return; // Early return - never touch toBlob in oracle mode
|
|
125
|
+
}
|
|
126
|
+
// BROWSER / UI PATH ONLY
|
|
71
127
|
const blob = await new Promise((resolve, reject) => {
|
|
72
128
|
canvas.toBlob((b) => b ? resolve(b) : reject(new Error('Failed to capture PNG')), 'image/png');
|
|
73
129
|
});
|
|
@@ -76,11 +132,10 @@ export async function runStaticMode(config, options) {
|
|
|
76
132
|
percent: 100,
|
|
77
133
|
message: 'Complete',
|
|
78
134
|
});
|
|
79
|
-
|
|
135
|
+
onComplete({
|
|
80
136
|
type: 'image',
|
|
81
137
|
blob,
|
|
82
|
-
};
|
|
83
|
-
onComplete(result);
|
|
138
|
+
});
|
|
84
139
|
}
|
|
85
140
|
catch (error) {
|
|
86
141
|
const err = error instanceof Error ? error : new Error(String(error));
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NexArt Code Mode Runtime SDK - Types
|
|
3
|
-
* Version: 1.
|
|
3
|
+
* Version: 1.6.0 (Protocol v1.2.0)
|
|
4
4
|
*
|
|
5
5
|
* Type definitions for the Code Mode runtime engine.
|
|
6
6
|
* This is the canonical type surface for @nexart/codemode-sdk.
|
|
@@ -17,6 +17,12 @@ export declare const PROTOCOL_IDENTITY: {
|
|
|
17
17
|
readonly deterministic: true;
|
|
18
18
|
};
|
|
19
19
|
export type RenderMode = 'static' | 'loop';
|
|
20
|
+
/**
|
|
21
|
+
* Runtime Canvas
|
|
22
|
+
* Abstraction for browser (HTMLCanvasElement) and Node (canvas package) environments.
|
|
23
|
+
* In Node, the `canvas` npm package provides an HTMLCanvasElement-compatible interface.
|
|
24
|
+
*/
|
|
25
|
+
export type RuntimeCanvas = HTMLCanvasElement;
|
|
20
26
|
export interface EngineConfig {
|
|
21
27
|
mode: RenderMode;
|
|
22
28
|
width?: number;
|
|
@@ -24,20 +30,36 @@ export interface EngineConfig {
|
|
|
24
30
|
duration?: number;
|
|
25
31
|
fps?: number;
|
|
26
32
|
}
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Render Result (Discriminated Union)
|
|
35
|
+
*
|
|
36
|
+
* Static mode can return either:
|
|
37
|
+
* - blob: For display/download (PNG)
|
|
38
|
+
* - imageData: For oracle hashing (raw pixels)
|
|
39
|
+
*
|
|
40
|
+
* Video mode returns blob with frame/duration metadata.
|
|
41
|
+
*/
|
|
42
|
+
export type RenderResult = {
|
|
43
|
+
type: 'image';
|
|
44
|
+
blob: Blob;
|
|
45
|
+
} | {
|
|
46
|
+
type: 'image';
|
|
47
|
+
imageData: ImageData;
|
|
48
|
+
} | {
|
|
49
|
+
type: 'video';
|
|
29
50
|
blob: Blob;
|
|
30
51
|
frames?: number;
|
|
31
52
|
duration?: number;
|
|
32
|
-
}
|
|
53
|
+
};
|
|
33
54
|
export interface RunOptions {
|
|
34
55
|
code: string;
|
|
35
56
|
seed?: number;
|
|
36
57
|
vars?: number[];
|
|
37
|
-
onPreview?: (canvas:
|
|
58
|
+
onPreview?: (canvas: RuntimeCanvas) => void;
|
|
38
59
|
onProgress?: (progress: ProgressInfo) => void;
|
|
39
60
|
onComplete: (result: RenderResult) => void;
|
|
40
61
|
onError?: (error: Error) => void;
|
|
62
|
+
returnImageData?: boolean;
|
|
41
63
|
}
|
|
42
64
|
export interface ProgressInfo {
|
|
43
65
|
phase: 'setup' | 'rendering' | 'encoding' | 'complete';
|
|
@@ -127,7 +149,7 @@ export interface ExecuteCodeModeResult {
|
|
|
127
149
|
metadata: ProtocolMetadata;
|
|
128
150
|
}
|
|
129
151
|
/**
|
|
130
|
-
* Builder Manifest (v1.
|
|
152
|
+
* Builder Manifest (v1.6.0)
|
|
131
153
|
*
|
|
132
154
|
* Passive, declarative metadata for builder attribution.
|
|
133
155
|
* This is data-only with no logic, rewards, or enforcement attached.
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;CAMpB,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexart/codemode-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "NexArt Code Mode SDK - Canonical execution engine for deterministic generative art",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/core-index.js",
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
"dist",
|
|
16
16
|
"README.md",
|
|
17
17
|
"CHANGELOG.md",
|
|
18
|
-
"CODE_MODE_PROTOCOL.md"
|
|
18
|
+
"CODE_MODE_PROTOCOL.md",
|
|
19
|
+
"LICENSE.md",
|
|
20
|
+
"builder.manifest.schema.json"
|
|
19
21
|
],
|
|
20
22
|
"scripts": {
|
|
21
23
|
"build": "tsc",
|