@nexart/cli 0.2.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/README.md +160 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +455 -0
- package/dist/index.js.map +1 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# @nexart/cli v0.2
|
|
2
|
+
|
|
3
|
+
Command-line interface for NexArt CodeMode — run, replay, and verify deterministic generative art.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @nexart/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
The CLI renders Code Mode sketches via a **remote canonical renderer** and creates verifiable snapshots.
|
|
14
|
+
|
|
15
|
+
**v0.2 features:**
|
|
16
|
+
- Real PNG output via remote renderer
|
|
17
|
+
- Snapshot v1 format with SHA-256 hashing
|
|
18
|
+
- Verify and replay commands
|
|
19
|
+
- Optional code embedding in snapshots
|
|
20
|
+
|
|
21
|
+
## Commands
|
|
22
|
+
|
|
23
|
+
### Run
|
|
24
|
+
|
|
25
|
+
Execute a sketch and create a snapshot:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# With remote renderer (default)
|
|
29
|
+
nexart run sketch.js --seed 12345 --out render.png
|
|
30
|
+
|
|
31
|
+
# With code embedded for standalone verify/replay
|
|
32
|
+
nexart run sketch.js --seed 12345 --include-code
|
|
33
|
+
|
|
34
|
+
# Offline mode (placeholder PNG)
|
|
35
|
+
nexart run sketch.js --renderer local
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Options:**
|
|
39
|
+
| Flag | Default | Description |
|
|
40
|
+
|------|---------|-------------|
|
|
41
|
+
| `--out, -o` | out.png | Output PNG path |
|
|
42
|
+
| `--seed, -s` | random | PRNG seed |
|
|
43
|
+
| `--vars, -v` | 0,0,0,0,0,0,0,0,0,0 | VAR values (comma-separated) |
|
|
44
|
+
| `--width, -w` | 1950 | Canvas width |
|
|
45
|
+
| `--height` | 2400 | Canvas height |
|
|
46
|
+
| `--renderer` | remote | `remote` or `local` |
|
|
47
|
+
| `--endpoint` | env/localhost:5000 | Remote renderer URL |
|
|
48
|
+
| `--include-code` | false | Embed code in snapshot |
|
|
49
|
+
| `--runtime-hash` | auto | Override runtime hash |
|
|
50
|
+
|
|
51
|
+
**Outputs:**
|
|
52
|
+
- `render.png` — The rendered image
|
|
53
|
+
- `render.snapshot.json` — Snapshot for replay/verify
|
|
54
|
+
|
|
55
|
+
### Verify
|
|
56
|
+
|
|
57
|
+
Check that a snapshot produces the expected output:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
nexart verify render.snapshot.json
|
|
61
|
+
|
|
62
|
+
# With external code file
|
|
63
|
+
nexart verify render.snapshot.json --code sketch.js
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Exit codes:**
|
|
67
|
+
- `0` — PASS (hashes match)
|
|
68
|
+
- `1` — FAIL (hashes differ or error)
|
|
69
|
+
|
|
70
|
+
### Replay
|
|
71
|
+
|
|
72
|
+
Re-execute from a snapshot:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
nexart replay render.snapshot.json --out replay.png
|
|
76
|
+
|
|
77
|
+
# With external code file
|
|
78
|
+
nexart replay render.snapshot.json --code sketch.js --out replay.png
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Remote Renderer
|
|
82
|
+
|
|
83
|
+
The CLI calls a canonical Node.js renderer endpoint for real PNG generation.
|
|
84
|
+
|
|
85
|
+
### Endpoint Configuration
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Via environment variable
|
|
89
|
+
export NEXART_RENDERER_ENDPOINT=http://localhost:5000
|
|
90
|
+
|
|
91
|
+
# Via CLI flag
|
|
92
|
+
nexart run sketch.js --endpoint http://render.nexart.io
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Expected API
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
POST /api/render
|
|
99
|
+
Content-Type: application/json
|
|
100
|
+
|
|
101
|
+
{
|
|
102
|
+
"code": "...",
|
|
103
|
+
"seed": 12345,
|
|
104
|
+
"VAR": [0,0,0,0,0,0,0,0,0,0],
|
|
105
|
+
"width": 1950,
|
|
106
|
+
"height": 2400,
|
|
107
|
+
"protocolVersion": "1.2.0"
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
Response: image/png (binary)
|
|
111
|
+
Headers:
|
|
112
|
+
X-Runtime-Hash: <hash>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Or JSON response:
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"pngBase64": "...",
|
|
119
|
+
"runtimeHash": "..."
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Snapshot Format (v1)
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"protocol": "nexart",
|
|
128
|
+
"protocolVersion": "1.2.0",
|
|
129
|
+
"runtime": "canonical",
|
|
130
|
+
"runtimeHash": "<sha256>",
|
|
131
|
+
"codeHash": "<sha256>",
|
|
132
|
+
"seed": 12345,
|
|
133
|
+
"VAR": [0,0,0,0,0,0,0,0,0,0],
|
|
134
|
+
"canvas": { "width": 1950, "height": 2400 },
|
|
135
|
+
"outputHash": "<sha256>",
|
|
136
|
+
"createdAt": "2026-01-24T...",
|
|
137
|
+
"code": "..." // optional, if --include-code
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Hash definitions:**
|
|
142
|
+
- `outputHash` = SHA-256 of PNG bytes
|
|
143
|
+
- `codeHash` = SHA-256 of normalized code
|
|
144
|
+
- `runtimeHash` = From renderer or SHA-256 of SDK version
|
|
145
|
+
|
|
146
|
+
## Offline Mode
|
|
147
|
+
|
|
148
|
+
For development without a renderer:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
nexart run sketch.js --renderer local
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
This creates a placeholder 1x1 PNG. Real local rendering is planned for v0.3.
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
MIT — Free for all use including commercial.
|
|
159
|
+
|
|
160
|
+
See [Core vs Edges](../../docs/core-vs-edges.md) for the NexArt business model.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @nexart/cli v0.2 — NexArt CodeMode CLI
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* - nexart run <file> — Execute via remote renderer and create snapshot
|
|
7
|
+
* - nexart replay <snapshot> — Re-execute from snapshot
|
|
8
|
+
* - nexart verify <snapshot> — Verify snapshot hash
|
|
9
|
+
*
|
|
10
|
+
* Remote rendering via canonical Node renderer endpoint.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @nexart/cli v0.2 — NexArt CodeMode CLI
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* - nexart run <file> — Execute via remote renderer and create snapshot
|
|
7
|
+
* - nexart replay <snapshot> — Re-execute from snapshot
|
|
8
|
+
* - nexart verify <snapshot> — Verify snapshot hash
|
|
9
|
+
*
|
|
10
|
+
* Remote rendering via canonical Node renderer endpoint.
|
|
11
|
+
*/
|
|
12
|
+
import yargs from 'yargs';
|
|
13
|
+
import { hideBin } from 'yargs/helpers';
|
|
14
|
+
import * as fs from 'fs';
|
|
15
|
+
import * as crypto from 'crypto';
|
|
16
|
+
import * as http from 'http';
|
|
17
|
+
import * as https from 'https';
|
|
18
|
+
const CLI_VERSION = '0.2.0';
|
|
19
|
+
const SDK_VERSION = '1.8.3';
|
|
20
|
+
const PROTOCOL_VERSION = '1.2.0';
|
|
21
|
+
const DEFAULT_ENDPOINT = process.env.NEXART_RENDERER_ENDPOINT || 'http://localhost:5000';
|
|
22
|
+
function sha256(data) {
|
|
23
|
+
const buffer = typeof data === 'string' ? Buffer.from(data, 'utf-8') : data;
|
|
24
|
+
return crypto.createHash('sha256').update(buffer).digest('hex');
|
|
25
|
+
}
|
|
26
|
+
function normalizeCode(code) {
|
|
27
|
+
return code
|
|
28
|
+
.replace(/\r\n/g, '\n')
|
|
29
|
+
.split('\n')
|
|
30
|
+
.map(line => line.trimEnd())
|
|
31
|
+
.join('\n')
|
|
32
|
+
.replace(/\n+$/, '') + '\n';
|
|
33
|
+
}
|
|
34
|
+
function hashCode(code) {
|
|
35
|
+
return sha256(normalizeCode(code));
|
|
36
|
+
}
|
|
37
|
+
function normalizeVAR(vars) {
|
|
38
|
+
const result = new Array(10).fill(0);
|
|
39
|
+
if (vars) {
|
|
40
|
+
for (let i = 0; i < Math.min(vars.length, 10); i++) {
|
|
41
|
+
result[i] = Math.max(0, Math.min(100, vars[i] ?? 0));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
function parseVars(varsStr) {
|
|
47
|
+
const parts = varsStr.split(',').map(s => parseInt(s.trim(), 10) || 0);
|
|
48
|
+
return normalizeVAR(parts);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Call remote renderer endpoint
|
|
52
|
+
*/
|
|
53
|
+
async function callRenderer(endpoint, code, seed, VAR, width, height) {
|
|
54
|
+
const url = new URL('/api/render', endpoint);
|
|
55
|
+
const isHttps = url.protocol === 'https:';
|
|
56
|
+
const httpModule = isHttps ? https : http;
|
|
57
|
+
const body = JSON.stringify({
|
|
58
|
+
code,
|
|
59
|
+
seed,
|
|
60
|
+
VAR,
|
|
61
|
+
width,
|
|
62
|
+
height,
|
|
63
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
64
|
+
});
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
const req = httpModule.request({
|
|
67
|
+
hostname: url.hostname,
|
|
68
|
+
port: url.port || (isHttps ? 443 : 80),
|
|
69
|
+
path: url.pathname,
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: {
|
|
72
|
+
'Content-Type': 'application/json',
|
|
73
|
+
'Content-Length': Buffer.byteLength(body),
|
|
74
|
+
},
|
|
75
|
+
}, (res) => {
|
|
76
|
+
const chunks = [];
|
|
77
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
78
|
+
res.on('end', () => {
|
|
79
|
+
const responseBuffer = Buffer.concat(chunks);
|
|
80
|
+
const contentType = res.headers['content-type'] || '';
|
|
81
|
+
// Handle binary PNG response
|
|
82
|
+
if (contentType.includes('image/png')) {
|
|
83
|
+
const runtimeHash = res.headers['x-runtime-hash'] || sha256(SDK_VERSION);
|
|
84
|
+
resolve({ pngBytes: responseBuffer, runtimeHash });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// Handle JSON response (with base64 PNG or error)
|
|
88
|
+
try {
|
|
89
|
+
const json = JSON.parse(responseBuffer.toString('utf-8'));
|
|
90
|
+
if (json.error) {
|
|
91
|
+
reject(new Error(`Renderer error: ${json.error}`));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (json.pngBase64) {
|
|
95
|
+
const pngBytes = Buffer.from(json.pngBase64, 'base64');
|
|
96
|
+
const runtimeHash = json.runtimeHash || sha256(SDK_VERSION);
|
|
97
|
+
resolve({ pngBytes, runtimeHash });
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
reject(new Error('Invalid renderer response: no PNG data'));
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
reject(new Error(`Failed to parse renderer response: ${e}`));
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
req.on('error', (e) => {
|
|
108
|
+
reject(new Error(`Failed to connect to renderer at ${endpoint}: ${e.message}`));
|
|
109
|
+
});
|
|
110
|
+
req.write(body);
|
|
111
|
+
req.end();
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Create a placeholder PNG (1x1 white pixel) for local mode
|
|
116
|
+
*/
|
|
117
|
+
function createPlaceholderPng() {
|
|
118
|
+
return Buffer.from([
|
|
119
|
+
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
|
|
120
|
+
0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
|
|
121
|
+
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
|
122
|
+
0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53,
|
|
123
|
+
0xDE, 0x00, 0x00, 0x00, 0x0C, 0x49, 0x44, 0x41,
|
|
124
|
+
0x54, 0x08, 0xD7, 0x63, 0xF8, 0xFF, 0xFF, 0x3F,
|
|
125
|
+
0x00, 0x05, 0xFE, 0x02, 0xFE, 0xDC, 0xCC, 0x59,
|
|
126
|
+
0xE7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E,
|
|
127
|
+
0x44, 0xAE, 0x42, 0x60, 0x82
|
|
128
|
+
]);
|
|
129
|
+
}
|
|
130
|
+
async function runCommand(file, options) {
|
|
131
|
+
console.log(`[nexart] Running: ${file}`);
|
|
132
|
+
console.log(`[nexart] Renderer: ${options.renderer}`);
|
|
133
|
+
if (!fs.existsSync(file)) {
|
|
134
|
+
console.error(`Error: File not found: ${file}`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
const code = fs.readFileSync(file, 'utf-8');
|
|
138
|
+
const codeHash = hashCode(code);
|
|
139
|
+
const VAR = parseVars(options.vars);
|
|
140
|
+
const { seed, width, height } = options;
|
|
141
|
+
console.log(`[nexart] Seed: ${seed}`);
|
|
142
|
+
console.log(`[nexart] VAR: [${VAR.join(', ')}]`);
|
|
143
|
+
console.log(`[nexart] Canvas: ${width}x${height}`);
|
|
144
|
+
let pngBytes;
|
|
145
|
+
let runtimeHash;
|
|
146
|
+
if (options.renderer === 'remote') {
|
|
147
|
+
console.log(`[nexart] Endpoint: ${options.endpoint}`);
|
|
148
|
+
try {
|
|
149
|
+
const result = await callRenderer(options.endpoint, code, seed, VAR, width, height);
|
|
150
|
+
pngBytes = result.pngBytes;
|
|
151
|
+
runtimeHash = options.runtimeHash || result.runtimeHash;
|
|
152
|
+
console.log(`[nexart] Received ${pngBytes.length} bytes from renderer`);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
console.error(`[nexart] Remote render failed: ${error}`);
|
|
156
|
+
console.error(`[nexart] Falling back to local placeholder`);
|
|
157
|
+
pngBytes = createPlaceholderPng();
|
|
158
|
+
runtimeHash = options.runtimeHash || sha256(SDK_VERSION);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
console.log(`[nexart] Using local placeholder (full local rendering planned for v0.3)`);
|
|
163
|
+
pngBytes = createPlaceholderPng();
|
|
164
|
+
runtimeHash = options.runtimeHash || sha256(SDK_VERSION);
|
|
165
|
+
}
|
|
166
|
+
const outputHash = sha256(pngBytes);
|
|
167
|
+
const snapshot = {
|
|
168
|
+
protocol: 'nexart',
|
|
169
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
170
|
+
runtime: 'canonical',
|
|
171
|
+
runtimeHash,
|
|
172
|
+
codeHash,
|
|
173
|
+
seed,
|
|
174
|
+
VAR,
|
|
175
|
+
canvas: { width, height },
|
|
176
|
+
outputHash,
|
|
177
|
+
createdAt: new Date().toISOString(),
|
|
178
|
+
};
|
|
179
|
+
if (options.includeCode) {
|
|
180
|
+
snapshot.code = code;
|
|
181
|
+
}
|
|
182
|
+
const outPath = options.out;
|
|
183
|
+
const snapshotPath = outPath.replace(/\.png$/i, '.snapshot.json');
|
|
184
|
+
fs.writeFileSync(outPath, pngBytes);
|
|
185
|
+
fs.writeFileSync(snapshotPath, JSON.stringify(snapshot, null, 2));
|
|
186
|
+
console.log(`[nexart] Output: ${outPath}`);
|
|
187
|
+
console.log(`[nexart] Snapshot: ${snapshotPath}`);
|
|
188
|
+
console.log(`[nexart] outputHash: ${outputHash}`);
|
|
189
|
+
console.log(`[nexart] codeHash: ${codeHash}`);
|
|
190
|
+
}
|
|
191
|
+
async function replayCommand(snapshotFile, options) {
|
|
192
|
+
console.log(`[nexart] Replaying from: ${snapshotFile}`);
|
|
193
|
+
if (!fs.existsSync(snapshotFile)) {
|
|
194
|
+
console.error(`Error: Snapshot not found: ${snapshotFile}`);
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
const snapshot = JSON.parse(fs.readFileSync(snapshotFile, 'utf-8'));
|
|
198
|
+
if (snapshot.protocol !== 'nexart') {
|
|
199
|
+
console.error('Error: Invalid snapshot format');
|
|
200
|
+
process.exit(1);
|
|
201
|
+
}
|
|
202
|
+
// Get code from snapshot, --code flag, or error
|
|
203
|
+
let code;
|
|
204
|
+
if (options.code && fs.existsSync(options.code)) {
|
|
205
|
+
code = fs.readFileSync(options.code, 'utf-8');
|
|
206
|
+
console.log(`[nexart] Using code from: ${options.code}`);
|
|
207
|
+
}
|
|
208
|
+
else if (snapshot.code) {
|
|
209
|
+
code = snapshot.code;
|
|
210
|
+
console.log(`[nexart] Using embedded code from snapshot`);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
console.error('Error: No code available. Provide --code <file> or use a snapshot with embedded code.');
|
|
214
|
+
console.error('Hint: Use --include-code when running to embed code in snapshot.');
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
console.log(`[nexart] Protocol: ${snapshot.protocolVersion}`);
|
|
218
|
+
console.log(`[nexart] Seed: ${snapshot.seed}`);
|
|
219
|
+
console.log(`[nexart] VAR: [${snapshot.VAR.join(', ')}]`);
|
|
220
|
+
console.log(`[nexart] Canvas: ${snapshot.canvas.width}x${snapshot.canvas.height}`);
|
|
221
|
+
let pngBytes;
|
|
222
|
+
if (options.renderer === 'remote') {
|
|
223
|
+
console.log(`[nexart] Endpoint: ${options.endpoint}`);
|
|
224
|
+
try {
|
|
225
|
+
const result = await callRenderer(options.endpoint, code, snapshot.seed, snapshot.VAR, snapshot.canvas.width, snapshot.canvas.height);
|
|
226
|
+
pngBytes = result.pngBytes;
|
|
227
|
+
console.log(`[nexart] Received ${pngBytes.length} bytes from renderer`);
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
console.error(`[nexart] Remote render failed: ${error}`);
|
|
231
|
+
pngBytes = createPlaceholderPng();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
pngBytes = createPlaceholderPng();
|
|
236
|
+
}
|
|
237
|
+
const outputHash = sha256(pngBytes);
|
|
238
|
+
fs.writeFileSync(options.out, pngBytes);
|
|
239
|
+
console.log(`[nexart] Output: ${options.out}`);
|
|
240
|
+
console.log(`[nexart] outputHash: ${outputHash}`);
|
|
241
|
+
}
|
|
242
|
+
async function verifyCommand(snapshotFile, options) {
|
|
243
|
+
console.log(`[nexart] Verifying: ${snapshotFile}`);
|
|
244
|
+
if (!fs.existsSync(snapshotFile)) {
|
|
245
|
+
console.error(`Error: Snapshot not found: ${snapshotFile}`);
|
|
246
|
+
process.exit(1);
|
|
247
|
+
}
|
|
248
|
+
const snapshot = JSON.parse(fs.readFileSync(snapshotFile, 'utf-8'));
|
|
249
|
+
if (snapshot.protocol !== 'nexart') {
|
|
250
|
+
console.error('Error: Invalid snapshot format');
|
|
251
|
+
process.exit(1);
|
|
252
|
+
}
|
|
253
|
+
// Get code
|
|
254
|
+
let code;
|
|
255
|
+
if (options.code && fs.existsSync(options.code)) {
|
|
256
|
+
code = fs.readFileSync(options.code, 'utf-8');
|
|
257
|
+
console.log(`[nexart] Using code from: ${options.code}`);
|
|
258
|
+
}
|
|
259
|
+
else if (snapshot.code) {
|
|
260
|
+
code = snapshot.code;
|
|
261
|
+
console.log(`[nexart] Using embedded code from snapshot`);
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
console.error('Error: No code available for verification.');
|
|
265
|
+
console.error('Provide --code <file> or use a snapshot with embedded code.');
|
|
266
|
+
console.error('Hint: Use --include-code when running to embed code in snapshot.');
|
|
267
|
+
process.exit(1);
|
|
268
|
+
}
|
|
269
|
+
// Verify codeHash matches
|
|
270
|
+
const computedCodeHash = hashCode(code);
|
|
271
|
+
if (computedCodeHash !== snapshot.codeHash) {
|
|
272
|
+
console.error(`[nexart] Code hash mismatch!`);
|
|
273
|
+
console.error(`[nexart] Expected: ${snapshot.codeHash}`);
|
|
274
|
+
console.error(`[nexart] Actual: ${computedCodeHash}`);
|
|
275
|
+
console.log(`[nexart] Result: FAIL (code changed)`);
|
|
276
|
+
process.exit(1);
|
|
277
|
+
}
|
|
278
|
+
const expected = snapshot.outputHash;
|
|
279
|
+
let actual;
|
|
280
|
+
if (options.renderer === 'remote') {
|
|
281
|
+
console.log(`[nexart] Endpoint: ${options.endpoint}`);
|
|
282
|
+
try {
|
|
283
|
+
const result = await callRenderer(options.endpoint, code, snapshot.seed, snapshot.VAR, snapshot.canvas.width, snapshot.canvas.height);
|
|
284
|
+
actual = sha256(result.pngBytes);
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
console.error(`[nexart] Remote render failed: ${error}`);
|
|
288
|
+
console.log(`[nexart] Result: FAIL (render error)`);
|
|
289
|
+
process.exit(1);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
actual = sha256(createPlaceholderPng());
|
|
294
|
+
}
|
|
295
|
+
console.log(`[nexart] Expected: ${expected}`);
|
|
296
|
+
console.log(`[nexart] Actual: ${actual}`);
|
|
297
|
+
if (expected === actual) {
|
|
298
|
+
console.log(`[nexart] Result: PASS`);
|
|
299
|
+
process.exit(0);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
console.log(`[nexart] Result: FAIL`);
|
|
303
|
+
process.exit(1);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
// CLI setup
|
|
307
|
+
yargs(hideBin(process.argv))
|
|
308
|
+
.command('run <file>', 'Execute a Code Mode sketch and create snapshot', (yargs) => {
|
|
309
|
+
return yargs
|
|
310
|
+
.positional('file', {
|
|
311
|
+
describe: 'Path to the sketch file',
|
|
312
|
+
type: 'string',
|
|
313
|
+
demandOption: true,
|
|
314
|
+
})
|
|
315
|
+
.option('out', {
|
|
316
|
+
alias: 'o',
|
|
317
|
+
describe: 'Output PNG path',
|
|
318
|
+
type: 'string',
|
|
319
|
+
default: 'out.png',
|
|
320
|
+
})
|
|
321
|
+
.option('seed', {
|
|
322
|
+
alias: 's',
|
|
323
|
+
describe: 'PRNG seed',
|
|
324
|
+
type: 'number',
|
|
325
|
+
default: Math.floor(Math.random() * 2147483647),
|
|
326
|
+
})
|
|
327
|
+
.option('vars', {
|
|
328
|
+
alias: 'v',
|
|
329
|
+
describe: 'Comma-separated VAR values (10 values, 0-100)',
|
|
330
|
+
type: 'string',
|
|
331
|
+
default: '0,0,0,0,0,0,0,0,0,0',
|
|
332
|
+
})
|
|
333
|
+
.option('width', {
|
|
334
|
+
alias: 'w',
|
|
335
|
+
describe: 'Canvas width',
|
|
336
|
+
type: 'number',
|
|
337
|
+
default: 1950,
|
|
338
|
+
})
|
|
339
|
+
.option('height', {
|
|
340
|
+
describe: 'Canvas height',
|
|
341
|
+
type: 'number',
|
|
342
|
+
default: 2400,
|
|
343
|
+
})
|
|
344
|
+
.option('renderer', {
|
|
345
|
+
describe: 'Renderer mode: local (placeholder) or remote (canonical)',
|
|
346
|
+
choices: ['local', 'remote'],
|
|
347
|
+
default: 'remote',
|
|
348
|
+
})
|
|
349
|
+
.option('endpoint', {
|
|
350
|
+
describe: 'Remote renderer endpoint URL',
|
|
351
|
+
type: 'string',
|
|
352
|
+
default: DEFAULT_ENDPOINT,
|
|
353
|
+
})
|
|
354
|
+
.option('runtime-hash', {
|
|
355
|
+
describe: 'Override runtime hash (advanced)',
|
|
356
|
+
type: 'string',
|
|
357
|
+
})
|
|
358
|
+
.option('include-code', {
|
|
359
|
+
describe: 'Embed code in snapshot for standalone replay/verify',
|
|
360
|
+
type: 'boolean',
|
|
361
|
+
default: false,
|
|
362
|
+
});
|
|
363
|
+
}, async (argv) => {
|
|
364
|
+
await runCommand(argv.file, {
|
|
365
|
+
out: argv.out,
|
|
366
|
+
seed: argv.seed,
|
|
367
|
+
vars: argv.vars,
|
|
368
|
+
width: argv.width,
|
|
369
|
+
height: argv.height,
|
|
370
|
+
renderer: argv.renderer,
|
|
371
|
+
endpoint: argv.endpoint,
|
|
372
|
+
runtimeHash: argv['runtime-hash'],
|
|
373
|
+
includeCode: argv['include-code'],
|
|
374
|
+
});
|
|
375
|
+
})
|
|
376
|
+
.command('replay <snapshot>', 'Re-execute from a snapshot file', (yargs) => {
|
|
377
|
+
return yargs
|
|
378
|
+
.positional('snapshot', {
|
|
379
|
+
describe: 'Path to snapshot JSON file',
|
|
380
|
+
type: 'string',
|
|
381
|
+
demandOption: true,
|
|
382
|
+
})
|
|
383
|
+
.option('out', {
|
|
384
|
+
alias: 'o',
|
|
385
|
+
describe: 'Output PNG path',
|
|
386
|
+
type: 'string',
|
|
387
|
+
default: 'replay.png',
|
|
388
|
+
})
|
|
389
|
+
.option('code', {
|
|
390
|
+
alias: 'c',
|
|
391
|
+
describe: 'Path to code file (if not embedded in snapshot)',
|
|
392
|
+
type: 'string',
|
|
393
|
+
})
|
|
394
|
+
.option('renderer', {
|
|
395
|
+
describe: 'Renderer mode',
|
|
396
|
+
choices: ['local', 'remote'],
|
|
397
|
+
default: 'remote',
|
|
398
|
+
})
|
|
399
|
+
.option('endpoint', {
|
|
400
|
+
describe: 'Remote renderer endpoint URL',
|
|
401
|
+
type: 'string',
|
|
402
|
+
default: DEFAULT_ENDPOINT,
|
|
403
|
+
});
|
|
404
|
+
}, async (argv) => {
|
|
405
|
+
await replayCommand(argv.snapshot, {
|
|
406
|
+
out: argv.out,
|
|
407
|
+
code: argv.code,
|
|
408
|
+
renderer: argv.renderer,
|
|
409
|
+
endpoint: argv.endpoint,
|
|
410
|
+
});
|
|
411
|
+
})
|
|
412
|
+
.command('verify <snapshot>', 'Verify a snapshot produces the expected output', (yargs) => {
|
|
413
|
+
return yargs
|
|
414
|
+
.positional('snapshot', {
|
|
415
|
+
describe: 'Path to snapshot JSON file',
|
|
416
|
+
type: 'string',
|
|
417
|
+
demandOption: true,
|
|
418
|
+
})
|
|
419
|
+
.option('code', {
|
|
420
|
+
alias: 'c',
|
|
421
|
+
describe: 'Path to code file (if not embedded in snapshot)',
|
|
422
|
+
type: 'string',
|
|
423
|
+
})
|
|
424
|
+
.option('renderer', {
|
|
425
|
+
describe: 'Renderer mode',
|
|
426
|
+
choices: ['local', 'remote'],
|
|
427
|
+
default: 'remote',
|
|
428
|
+
})
|
|
429
|
+
.option('endpoint', {
|
|
430
|
+
describe: 'Remote renderer endpoint URL',
|
|
431
|
+
type: 'string',
|
|
432
|
+
default: DEFAULT_ENDPOINT,
|
|
433
|
+
});
|
|
434
|
+
}, async (argv) => {
|
|
435
|
+
await verifyCommand(argv.snapshot, {
|
|
436
|
+
code: argv.code,
|
|
437
|
+
renderer: argv.renderer,
|
|
438
|
+
endpoint: argv.endpoint,
|
|
439
|
+
});
|
|
440
|
+
})
|
|
441
|
+
.demandCommand(1, 'You must provide a command')
|
|
442
|
+
.help()
|
|
443
|
+
.version(CLI_VERSION)
|
|
444
|
+
.epilog(`
|
|
445
|
+
Environment Variables:
|
|
446
|
+
NEXART_RENDERER_ENDPOINT Default remote renderer URL (default: http://localhost:5000)
|
|
447
|
+
|
|
448
|
+
Examples:
|
|
449
|
+
nexart run sketch.js --seed 12345 --include-code
|
|
450
|
+
nexart verify out.snapshot.json
|
|
451
|
+
nexart replay out.snapshot.json --out replay.png
|
|
452
|
+
nexart run sketch.js --renderer local # Use placeholder (offline)
|
|
453
|
+
`)
|
|
454
|
+
.parse();
|
|
455
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,GAAG,OAAO,CAAC;AAC5B,MAAM,WAAW,GAAG,OAAO,CAAC;AAC5B,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAEjC,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,uBAAuB,CAAC;AA2BzF,SAAS,MAAM,CAAC,IAAqB;IACnC,MAAM,MAAM,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI;SACR,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC;SACtB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;SAC3B,IAAI,CAAC,IAAI,CAAC;SACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC;AAChC,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,YAAY,CAAC,IAAe;IACnC,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrC,IAAI,IAAI,EAAE,CAAC;QACT,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACnD,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,SAAS,CAAC,OAAe;IAChC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,YAAY,CACzB,QAAgB,EAChB,IAAY,EACZ,IAAY,EACZ,GAAa,EACb,KAAa,EACb,MAAc;IAEd,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC;IAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAE1C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAC1B,IAAI;QACJ,IAAI;QACJ,GAAG;QACH,KAAK;QACL,MAAM;QACN,eAAe,EAAE,gBAAgB;KAClC,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAC5B;YACE,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACtC,IAAI,EAAE,GAAG,CAAC,QAAQ;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;aAC1C;SACF,EACD,CAAC,GAAG,EAAE,EAAE;YACN,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC7C,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;gBAEtD,6BAA6B;gBAC7B,IAAI,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;oBACtC,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAW,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC;oBACnF,OAAO,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;oBACnD,OAAO;gBACT,CAAC;gBAED,kDAAkD;gBAClD,IAAI,CAAC;oBACH,MAAM,IAAI,GAAmB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC1E,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;wBACf,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;wBACnD,OAAO;oBACT,CAAC;oBACD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;wBACnB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;wBACvD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC;wBAC5D,OAAO,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;wBACnC,OAAO;oBACT,CAAC;oBACD,MAAM,CAAC,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;gBAC9D,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,IAAI,KAAK,CAAC,sCAAsC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CACF,CAAC;QAEF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;YACpB,MAAM,CAAC,IAAI,KAAK,CAAC,oCAAoC,QAAQ,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChB,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB;IAC3B,OAAO,MAAM,CAAC,IAAI,CAAC;QACjB,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;QAC9C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;QAC9C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;QAC9C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;QAC9C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;QAC9C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;QAC9C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;QAC9C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;QAC9C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;KAC7B,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,IAAY,EAAE,OAUvC;IACC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEtD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC;IAEnD,IAAI,QAAgB,CAAC;IACrB,IAAI,WAAmB,CAAC;IAExB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YACpF,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YAC3B,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,qBAAqB,QAAQ,CAAC,MAAM,sBAAsB,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kCAAkC,KAAK,EAAE,CAAC,CAAC;YACzD,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAC5D,QAAQ,GAAG,oBAAoB,EAAE,CAAC;YAClC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;QACxF,QAAQ,GAAG,oBAAoB,EAAE,CAAC;QAClC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEpC,MAAM,QAAQ,GAAqB;QACjC,QAAQ,EAAE,QAAQ;QAClB,eAAe,EAAE,gBAAgB;QACjC,OAAO,EAAE,WAAW;QACpB,WAAW;QACX,QAAQ;QACR,IAAI;QACJ,GAAG;QACH,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;QACzB,UAAU;QACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC;IAC5B,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;IAElE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACpC,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAElE,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,sBAAsB,YAAY,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,YAAoB,EAAE,OAKlD;IACC,OAAO,CAAC,GAAG,CAAC,4BAA4B,YAAY,EAAE,CAAC,CAAC;IAExD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,8BAA8B,YAAY,EAAE,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAqB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IAEtF,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,gDAAgD;IAChD,IAAI,IAAY,CAAC;IACjB,IAAI,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,6BAA6B,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;SAAM,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QACzB,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,uFAAuF,CAAC,CAAC;QACvG,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;QAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,QAAQ,CAAC,eAAe,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,kBAAkB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,kBAAkB,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,oBAAoB,QAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAEnF,IAAI,QAAgB,CAAC;IAErB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAC/B,OAAO,CAAC,QAAQ,EAChB,IAAI,EACJ,QAAQ,CAAC,IAAI,EACb,QAAQ,CAAC,GAAG,EACZ,QAAQ,CAAC,MAAM,CAAC,KAAK,EACrB,QAAQ,CAAC,MAAM,CAAC,MAAM,CACvB,CAAC;YACF,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,qBAAqB,QAAQ,CAAC,MAAM,sBAAsB,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kCAAkC,KAAK,EAAE,CAAC,CAAC;YACzD,QAAQ,GAAG,oBAAoB,EAAE,CAAC;QACpC,CAAC;IACH,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,oBAAoB,EAAE,CAAC;IACpC,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEpC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,YAAoB,EAAE,OAIlD;IACC,OAAO,CAAC,GAAG,CAAC,uBAAuB,YAAY,EAAE,CAAC,CAAC;IAEnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,8BAA8B,YAAY,EAAE,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAqB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IAEtF,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,WAAW;IACX,IAAI,IAAY,CAAC;IACjB,IAAI,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,6BAA6B,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;SAAM,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QACzB,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC5D,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;QAC7E,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;QAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,0BAA0B;IAC1B,MAAM,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,gBAAgB,KAAK,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC3C,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC9C,OAAO,CAAC,KAAK,CAAC,sBAAsB,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,KAAK,CAAC,sBAAsB,gBAAgB,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC;IACrC,IAAI,MAAc,CAAC;IAEnB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAC/B,OAAO,CAAC,QAAQ,EAChB,IAAI,EACJ,QAAQ,CAAC,IAAI,EACb,QAAQ,CAAC,GAAG,EACZ,QAAQ,CAAC,MAAM,CAAC,KAAK,EACrB,QAAQ,CAAC,MAAM,CAAC,MAAM,CACvB,CAAC;YACF,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kCAAkC,KAAK,EAAE,CAAC,CAAC;YACzD,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;IAE5C,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,YAAY;AACZ,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KACzB,OAAO,CACN,YAAY,EACZ,gDAAgD,EAChD,CAAC,KAAK,EAAE,EAAE;IACR,OAAO,KAAK;SACT,UAAU,CAAC,MAAM,EAAE;QAClB,QAAQ,EAAE,yBAAyB;QACnC,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;KACnB,CAAC;SACD,MAAM,CAAC,KAAK,EAAE;QACb,KAAK,EAAE,GAAG;QACV,QAAQ,EAAE,iBAAiB;QAC3B,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,SAAS;KACnB,CAAC;SACD,MAAM,CAAC,MAAM,EAAE;QACd,KAAK,EAAE,GAAG;QACV,QAAQ,EAAE,WAAW;QACrB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC;KAChD,CAAC;SACD,MAAM,CAAC,MAAM,EAAE;QACd,KAAK,EAAE,GAAG;QACV,QAAQ,EAAE,+CAA+C;QACzD,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,qBAAqB;KAC/B,CAAC;SACD,MAAM,CAAC,OAAO,EAAE;QACf,KAAK,EAAE,GAAG;QACV,QAAQ,EAAE,cAAc;QACxB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,IAAI;KACd,CAAC;SACD,MAAM,CAAC,QAAQ,EAAE;QAChB,QAAQ,EAAE,eAAe;QACzB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,IAAI;KACd,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,QAAQ,EAAE,0DAA0D;QACpE,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAU;QACrC,OAAO,EAAE,QAAiB;KAC3B,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,QAAQ,EAAE,8BAA8B;QACxC,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,gBAAgB;KAC1B,CAAC;SACD,MAAM,CAAC,cAAc,EAAE;QACtB,QAAQ,EAAE,kCAAkC;QAC5C,IAAI,EAAE,QAAQ;KACf,CAAC;SACD,MAAM,CAAC,cAAc,EAAE;QACtB,QAAQ,EAAE,qDAAqD;QAC/D,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACP,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACb,MAAM,UAAU,CAAC,IAAI,CAAC,IAAc,EAAE;QACpC,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC;QACjC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC;KAClC,CAAC,CAAC;AACL,CAAC,CACF;KACA,OAAO,CACN,mBAAmB,EACnB,iCAAiC,EACjC,CAAC,KAAK,EAAE,EAAE;IACR,OAAO,KAAK;SACT,UAAU,CAAC,UAAU,EAAE;QACtB,QAAQ,EAAE,4BAA4B;QACtC,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;KACnB,CAAC;SACD,MAAM,CAAC,KAAK,EAAE;QACb,KAAK,EAAE,GAAG;QACV,QAAQ,EAAE,iBAAiB;QAC3B,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,YAAY;KACtB,CAAC;SACD,MAAM,CAAC,MAAM,EAAE;QACd,KAAK,EAAE,GAAG;QACV,QAAQ,EAAE,iDAAiD;QAC3D,IAAI,EAAE,QAAQ;KACf,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAU;QACrC,OAAO,EAAE,QAAiB;KAC3B,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,QAAQ,EAAE,8BAA8B;QACxC,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,gBAAgB;KAC1B,CAAC,CAAC;AACP,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACb,MAAM,aAAa,CAAC,IAAI,CAAC,QAAkB,EAAE;QAC3C,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;AACL,CAAC,CACF;KACA,OAAO,CACN,mBAAmB,EACnB,gDAAgD,EAChD,CAAC,KAAK,EAAE,EAAE;IACR,OAAO,KAAK;SACT,UAAU,CAAC,UAAU,EAAE;QACtB,QAAQ,EAAE,4BAA4B;QACtC,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;KACnB,CAAC;SACD,MAAM,CAAC,MAAM,EAAE;QACd,KAAK,EAAE,GAAG;QACV,QAAQ,EAAE,iDAAiD;QAC3D,IAAI,EAAE,QAAQ;KACf,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAU;QACrC,OAAO,EAAE,QAAiB;KAC3B,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,QAAQ,EAAE,8BAA8B;QACxC,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,gBAAgB;KAC1B,CAAC,CAAC;AACP,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACb,MAAM,aAAa,CAAC,IAAI,CAAC,QAAkB,EAAE;QAC3C,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;AACL,CAAC,CACF;KACA,aAAa,CAAC,CAAC,EAAE,4BAA4B,CAAC;KAC9C,IAAI,EAAE;KACN,OAAO,CAAC,WAAW,CAAC;KACpB,MAAM,CAAC;;;;;;;;;GASP,CAAC;KACD,KAAK,EAAE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nexart/cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "NexArt CodeMode CLI - Run, replay, and verify deterministic generative art",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"nexart": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsx src/index.ts"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"nexart",
|
|
16
|
+
"codemode",
|
|
17
|
+
"generative-art",
|
|
18
|
+
"deterministic",
|
|
19
|
+
"cli",
|
|
20
|
+
"nft",
|
|
21
|
+
"verification"
|
|
22
|
+
],
|
|
23
|
+
"author": "NexArt",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"yargs": "^17.7.2"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^20.0.0",
|
|
30
|
+
"@types/yargs": "^17.0.32",
|
|
31
|
+
"typescript": "^5.0.0",
|
|
32
|
+
"tsx": "^4.0.0"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18.0.0"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"README.md"
|
|
40
|
+
]
|
|
41
|
+
}
|