@nexart/codemode-sdk 1.6.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/README.md +221 -9
  3. package/dist/core-index.d.ts +1 -1
  4. package/dist/core-index.js +1 -1
  5. package/dist/entry/browser.d.ts +43 -0
  6. package/dist/entry/browser.d.ts.map +1 -0
  7. package/dist/entry/browser.js +63 -0
  8. package/dist/entry/node.d.ts +23 -0
  9. package/dist/entry/node.d.ts.map +1 -0
  10. package/dist/entry/node.js +34 -0
  11. package/dist/index.d.ts +14 -33
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +41 -33
  14. package/dist/runtime.d.ts +52 -0
  15. package/dist/runtime.d.ts.map +1 -0
  16. package/dist/runtime.js +219 -0
  17. package/dist/sdk/codemode/builder-manifest.d.ts +79 -0
  18. package/dist/sdk/codemode/builder-manifest.d.ts.map +1 -0
  19. package/dist/sdk/codemode/builder-manifest.js +97 -0
  20. package/dist/sdk/codemode/core-index.d.ts +21 -0
  21. package/dist/sdk/codemode/core-index.d.ts.map +1 -0
  22. package/dist/sdk/codemode/core-index.js +26 -0
  23. package/dist/sdk/codemode/engine.d.ts +24 -0
  24. package/dist/sdk/codemode/engine.d.ts.map +1 -0
  25. package/dist/sdk/codemode/engine.js +67 -0
  26. package/dist/sdk/codemode/execute.d.ts +46 -0
  27. package/dist/sdk/codemode/execute.d.ts.map +1 -0
  28. package/dist/sdk/codemode/execute.js +283 -0
  29. package/dist/sdk/codemode/execution-sandbox.d.ts +107 -0
  30. package/dist/sdk/codemode/execution-sandbox.d.ts.map +1 -0
  31. package/dist/sdk/codemode/execution-sandbox.js +207 -0
  32. package/dist/sdk/codemode/index.d.ts +31 -0
  33. package/dist/sdk/codemode/index.d.ts.map +1 -0
  34. package/dist/sdk/codemode/index.js +63 -0
  35. package/dist/sdk/codemode/loop-engine.d.ts +22 -0
  36. package/dist/sdk/codemode/loop-engine.d.ts.map +1 -0
  37. package/dist/sdk/codemode/loop-engine.js +229 -0
  38. package/dist/sdk/codemode/noise-bridge.d.ts +44 -0
  39. package/dist/sdk/codemode/noise-bridge.d.ts.map +1 -0
  40. package/dist/sdk/codemode/noise-bridge.js +68 -0
  41. package/dist/sdk/codemode/noise-engine.d.ts +74 -0
  42. package/dist/sdk/codemode/noise-engine.d.ts.map +1 -0
  43. package/dist/sdk/codemode/noise-engine.js +132 -0
  44. package/dist/sdk/codemode/noise-sketches/fractalNoise.d.ts +11 -0
  45. package/dist/sdk/codemode/noise-sketches/fractalNoise.d.ts.map +1 -0
  46. package/dist/sdk/codemode/noise-sketches/fractalNoise.js +121 -0
  47. package/dist/sdk/codemode/noise-sketches/index.d.ts +21 -0
  48. package/dist/sdk/codemode/noise-sketches/index.d.ts.map +1 -0
  49. package/dist/sdk/codemode/noise-sketches/index.js +28 -0
  50. package/dist/sdk/codemode/p5-runtime.d.ts +75 -0
  51. package/dist/sdk/codemode/p5-runtime.d.ts.map +1 -0
  52. package/dist/sdk/codemode/p5-runtime.js +1031 -0
  53. package/dist/sdk/codemode/sound-bridge.d.ts +89 -0
  54. package/dist/sdk/codemode/sound-bridge.d.ts.map +1 -0
  55. package/dist/sdk/codemode/sound-bridge.js +128 -0
  56. package/dist/sdk/codemode/soundart-engine.d.ts +87 -0
  57. package/dist/sdk/codemode/soundart-engine.d.ts.map +1 -0
  58. package/dist/sdk/codemode/soundart-engine.js +173 -0
  59. package/dist/sdk/codemode/soundart-sketches/chladniBloom.d.ts +3 -0
  60. package/dist/sdk/codemode/soundart-sketches/chladniBloom.d.ts.map +1 -0
  61. package/dist/sdk/codemode/soundart-sketches/chladniBloom.js +53 -0
  62. package/dist/sdk/codemode/soundart-sketches/dualVortex.d.ts +3 -0
  63. package/dist/sdk/codemode/soundart-sketches/dualVortex.d.ts.map +1 -0
  64. package/dist/sdk/codemode/soundart-sketches/dualVortex.js +67 -0
  65. package/dist/sdk/codemode/soundart-sketches/geometryIllusion.d.ts +3 -0
  66. package/dist/sdk/codemode/soundart-sketches/geometryIllusion.d.ts.map +1 -0
  67. package/dist/sdk/codemode/soundart-sketches/geometryIllusion.js +89 -0
  68. package/dist/sdk/codemode/soundart-sketches/index.d.ts +39 -0
  69. package/dist/sdk/codemode/soundart-sketches/index.d.ts.map +1 -0
  70. package/dist/sdk/codemode/soundart-sketches/index.js +72 -0
  71. package/dist/sdk/codemode/soundart-sketches/isoflow.d.ts +3 -0
  72. package/dist/sdk/codemode/soundart-sketches/isoflow.d.ts.map +1 -0
  73. package/dist/sdk/codemode/soundart-sketches/isoflow.js +60 -0
  74. package/dist/sdk/codemode/soundart-sketches/loomWeave.d.ts +3 -0
  75. package/dist/sdk/codemode/soundart-sketches/loomWeave.d.ts.map +1 -0
  76. package/dist/sdk/codemode/soundart-sketches/loomWeave.js +59 -0
  77. package/dist/sdk/codemode/soundart-sketches/noiseTerraces.d.ts +3 -0
  78. package/dist/sdk/codemode/soundart-sketches/noiseTerraces.d.ts.map +1 -0
  79. package/dist/sdk/codemode/soundart-sketches/noiseTerraces.js +53 -0
  80. package/dist/sdk/codemode/soundart-sketches/orb.d.ts +3 -0
  81. package/dist/sdk/codemode/soundart-sketches/orb.d.ts.map +1 -0
  82. package/dist/sdk/codemode/soundart-sketches/orb.js +50 -0
  83. package/dist/sdk/codemode/soundart-sketches/pixelGlyphs.d.ts +3 -0
  84. package/dist/sdk/codemode/soundart-sketches/pixelGlyphs.d.ts.map +1 -0
  85. package/dist/sdk/codemode/soundart-sketches/pixelGlyphs.js +72 -0
  86. package/dist/sdk/codemode/soundart-sketches/prismFlowFields.d.ts +3 -0
  87. package/dist/sdk/codemode/soundart-sketches/prismFlowFields.d.ts.map +1 -0
  88. package/dist/sdk/codemode/soundart-sketches/prismFlowFields.js +51 -0
  89. package/dist/sdk/codemode/soundart-sketches/radialBurst.d.ts +3 -0
  90. package/dist/sdk/codemode/soundart-sketches/radialBurst.d.ts.map +1 -0
  91. package/dist/sdk/codemode/soundart-sketches/radialBurst.js +60 -0
  92. package/dist/sdk/codemode/soundart-sketches/resonantSoundBodies.d.ts +3 -0
  93. package/dist/sdk/codemode/soundart-sketches/resonantSoundBodies.d.ts.map +1 -0
  94. package/dist/sdk/codemode/soundart-sketches/resonantSoundBodies.js +89 -0
  95. package/dist/sdk/codemode/soundart-sketches/rings.d.ts +11 -0
  96. package/dist/sdk/codemode/soundart-sketches/rings.d.ts.map +1 -0
  97. package/dist/sdk/codemode/soundart-sketches/rings.js +89 -0
  98. package/dist/sdk/codemode/soundart-sketches/squares.d.ts +3 -0
  99. package/dist/sdk/codemode/soundart-sketches/squares.d.ts.map +1 -0
  100. package/dist/sdk/codemode/soundart-sketches/squares.js +52 -0
  101. package/dist/sdk/codemode/soundart-sketches/waveStripes.d.ts +3 -0
  102. package/dist/sdk/codemode/soundart-sketches/waveStripes.d.ts.map +1 -0
  103. package/dist/sdk/codemode/soundart-sketches/waveStripes.js +44 -0
  104. package/dist/sdk/codemode/static-engine.d.ts +20 -0
  105. package/dist/sdk/codemode/static-engine.d.ts.map +1 -0
  106. package/dist/sdk/codemode/static-engine.js +144 -0
  107. package/dist/sdk/codemode/types.d.ts +191 -0
  108. package/dist/sdk/codemode/types.d.ts.map +1 -0
  109. package/dist/sdk/codemode/types.js +32 -0
  110. package/dist/shared/noiseSnapshot.d.ts +59 -0
  111. package/dist/shared/noiseSnapshot.d.ts.map +1 -0
  112. package/dist/shared/noiseSnapshot.js +72 -0
  113. package/dist/shared/soundSnapshot.d.ts +94 -0
  114. package/dist/shared/soundSnapshot.d.ts.map +1 -0
  115. package/dist/shared/soundSnapshot.js +128 -0
  116. package/dist/static-engine.d.ts.map +1 -1
  117. package/dist/static-engine.js +24 -11
  118. package/examples/basic.ts +61 -0
  119. package/examples/preflight-test.ts +275 -0
  120. package/examples/verify.ts +151 -0
  121. package/package.json +45 -5
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @nexart/codemode-sdk — Basic Example
3
+ *
4
+ * Demonstrates the agent-first runtime API for deterministic execution.
5
+ *
6
+ * Run: npm run example:basic
7
+ */
8
+
9
+ import { createRuntime } from '../runtime';
10
+
11
+ console.log('╔══════════════════════════════════════════════════════════════╗');
12
+ console.log('║ NexArt Code Mode SDK — Basic Example ║');
13
+ console.log('╚══════════════════════════════════════════════════════════════╝');
14
+ console.log();
15
+
16
+ const runtime = createRuntime({
17
+ seed: 'demo-seed-42',
18
+ vars: [50, 75, 25],
19
+ strict: true,
20
+ mode: 'static',
21
+ metadata: { artist: 'demo', project: 'example' }
22
+ });
23
+
24
+ console.log('Runtime State:');
25
+ console.log(JSON.stringify(runtime.getState(), null, 2));
26
+ console.log();
27
+
28
+ console.log('Digest:', runtime.digest());
29
+ console.log('Seed (numeric):', runtime.getSeed());
30
+ console.log('Strict mode:', runtime.strict);
31
+ console.log();
32
+
33
+ console.log('Deterministic random values:');
34
+ const randoms: number[] = [];
35
+ for (let i = 0; i < 5; i++) {
36
+ const val = runtime.random();
37
+ randoms.push(val);
38
+ console.log(` random() #${i + 1}: ${val.toFixed(8)}`);
39
+ }
40
+ console.log();
41
+
42
+ console.log('Deterministic noise values:');
43
+ for (let i = 0; i < 5; i++) {
44
+ const x = i * 0.5;
45
+ const val = runtime.noise(x, 0.5);
46
+ console.log(` noise(${x}, 0.5): ${val.toFixed(8)}`);
47
+ }
48
+ console.log();
49
+
50
+ console.log('Running code in strict mode...');
51
+ const result = runtime.run(() => {
52
+ let sum = 0;
53
+ for (let i = 0; i < 10; i++) {
54
+ sum += runtime.random();
55
+ }
56
+ return sum;
57
+ });
58
+ console.log(` Sum of 10 random values: ${result.toFixed(8)}`);
59
+ console.log();
60
+
61
+ console.log('✅ Basic example completed successfully!');
@@ -0,0 +1,275 @@
1
+ /**
2
+ * @nexart/codemode-sdk — Preflight Release Tests
3
+ *
4
+ * Extended verification tests for v1.8.0 release validation.
5
+ * Tests strict mode restoration, error messages, and cross-env digest parity.
6
+ *
7
+ * Run: npx tsx examples/preflight-test.ts
8
+ */
9
+
10
+ import { createRuntime, RUNTIME_VERSION } from '../runtime';
11
+
12
+ console.log('╔══════════════════════════════════════════════════════════════╗');
13
+ console.log('║ NexArt Code Mode SDK — Preflight Release Tests ║');
14
+ console.log(`║ Version: ${RUNTIME_VERSION.padEnd(52)}║`);
15
+ console.log('╚══════════════════════════════════════════════════════════════╝');
16
+ console.log();
17
+
18
+ let passCount = 0;
19
+ let failCount = 0;
20
+
21
+ function test(name: string, fn: () => boolean): void {
22
+ try {
23
+ const result = fn();
24
+ if (result) {
25
+ console.log(`✅ PASS: ${name}`);
26
+ passCount++;
27
+ } else {
28
+ console.log(`❌ FAIL: ${name}`);
29
+ failCount++;
30
+ }
31
+ } catch (error: any) {
32
+ console.log(`❌ FAIL: ${name} — ${error.message}`);
33
+ failCount++;
34
+ }
35
+ }
36
+
37
+ console.log('TEST GROUP 1: Strict Mode Restoration on Throw');
38
+ console.log('─'.repeat(60));
39
+
40
+ test('Strict mode restores Math.random after user code throws', () => {
41
+ const runtime = createRuntime({ seed: 12345, strict: true });
42
+ const originalMathRandom = Math.random;
43
+
44
+ try {
45
+ runtime.run(() => {
46
+ throw new Error('User code explosion');
47
+ });
48
+ } catch {
49
+ // Expected
50
+ }
51
+
52
+ const restored = Math.random === originalMathRandom;
53
+ if (!restored) {
54
+ console.log(' ⚠️ Math.random was NOT restored after throw');
55
+ }
56
+ return restored;
57
+ });
58
+
59
+ test('Strict mode restores Date.now after user code throws', () => {
60
+ const runtime = createRuntime({ seed: 12345, strict: true });
61
+ const originalDateNow = Date.now;
62
+
63
+ try {
64
+ runtime.run(() => {
65
+ throw new Error('User code explosion');
66
+ });
67
+ } catch {
68
+ // Expected
69
+ }
70
+
71
+ const restored = Date.now === originalDateNow;
72
+ if (!restored) {
73
+ console.log(' ⚠️ Date.now was NOT restored after throw');
74
+ }
75
+ return restored;
76
+ });
77
+
78
+ test('Strict mode restores performance.now after user code throws', () => {
79
+ const runtime = createRuntime({ seed: 12345, strict: true });
80
+ const hasPerformance = typeof performance !== 'undefined' && performance !== null;
81
+
82
+ if (!hasPerformance) {
83
+ console.log(' ℹ️ performance object not available, skipping');
84
+ return true;
85
+ }
86
+
87
+ const originalPerformanceNow = performance.now;
88
+
89
+ try {
90
+ runtime.run(() => {
91
+ throw new Error('User code explosion');
92
+ });
93
+ } catch {
94
+ // Expected
95
+ }
96
+
97
+ const restored = performance.now === originalPerformanceNow;
98
+ if (!restored) {
99
+ console.log(' ⚠️ performance.now was NOT restored after throw');
100
+ }
101
+ return restored;
102
+ });
103
+
104
+ console.log();
105
+ console.log('TEST GROUP 2: Strict Mode Error Messages');
106
+ console.log('─'.repeat(60));
107
+
108
+ test('Math.random error message is actionable', () => {
109
+ const runtime = createRuntime({ seed: 12345, strict: true });
110
+
111
+ try {
112
+ runtime.run(() => Math.random());
113
+ return false;
114
+ } catch (error: any) {
115
+ const expected = 'NEXART_STRICT: Non-deterministic API used: Math.random. Use runtime.random() instead.';
116
+ const match = error.message === expected;
117
+ if (!match) {
118
+ console.log(` Expected: "${expected}"`);
119
+ console.log(` Got: "${error.message}"`);
120
+ }
121
+ return match;
122
+ }
123
+ });
124
+
125
+ test('Date.now error message is actionable', () => {
126
+ const runtime = createRuntime({ seed: 12345, strict: true });
127
+
128
+ try {
129
+ runtime.run(() => Date.now());
130
+ return false;
131
+ } catch (error: any) {
132
+ const expected = 'NEXART_STRICT: Non-deterministic API used: Date.now. Pass time as an input or use deterministic counters.';
133
+ const match = error.message === expected;
134
+ if (!match) {
135
+ console.log(` Expected: "${expected}"`);
136
+ console.log(` Got: "${error.message}"`);
137
+ }
138
+ return match;
139
+ }
140
+ });
141
+
142
+ test('performance.now error message is actionable', () => {
143
+ const runtime = createRuntime({ seed: 12345, strict: true });
144
+ const hasPerformance = typeof performance !== 'undefined' && performance !== null;
145
+
146
+ if (!hasPerformance) {
147
+ console.log(' ℹ️ performance object not available, skipping');
148
+ return true;
149
+ }
150
+
151
+ try {
152
+ runtime.run(() => performance.now());
153
+ return false;
154
+ } catch (error: any) {
155
+ const expected = 'NEXART_STRICT: Non-deterministic API used: performance.now.';
156
+ const match = error.message === expected;
157
+ if (!match) {
158
+ console.log(` Expected: "${expected}"`);
159
+ console.log(` Got: "${error.message}"`);
160
+ }
161
+ return match;
162
+ }
163
+ });
164
+
165
+ console.log();
166
+ console.log('TEST GROUP 3: Digest Determinism');
167
+ console.log('─'.repeat(60));
168
+
169
+ test('Digest is stable across multiple calls', () => {
170
+ const config = { seed: 'stable-digest-test', vars: [10, 20, 30], mode: 'static' as const };
171
+ const runtime1 = createRuntime(config);
172
+ const runtime2 = createRuntime(config);
173
+
174
+ const digest1 = runtime1.digest();
175
+ const digest2 = runtime2.digest();
176
+
177
+ if (digest1 !== digest2) {
178
+ console.log(` Digest 1: ${digest1}`);
179
+ console.log(` Digest 2: ${digest2}`);
180
+ }
181
+ return digest1 === digest2;
182
+ });
183
+
184
+ test('Digest changes when seed changes', () => {
185
+ const runtime1 = createRuntime({ seed: 'seed-a', vars: [10, 20, 30] });
186
+ const runtime2 = createRuntime({ seed: 'seed-b', vars: [10, 20, 30] });
187
+
188
+ return runtime1.digest() !== runtime2.digest();
189
+ });
190
+
191
+ test('Digest changes when vars change', () => {
192
+ const runtime1 = createRuntime({ seed: 'same-seed', vars: [10, 20, 30] });
193
+ const runtime2 = createRuntime({ seed: 'same-seed', vars: [10, 20, 31] });
194
+
195
+ return runtime1.digest() !== runtime2.digest();
196
+ });
197
+
198
+ test('Digest changes when mode changes', () => {
199
+ const runtime1 = createRuntime({ seed: 'same-seed', vars: [10, 20, 30], mode: 'static' });
200
+ const runtime2 = createRuntime({ seed: 'same-seed', vars: [10, 20, 30], mode: 'loop' });
201
+
202
+ return runtime1.digest() !== runtime2.digest();
203
+ });
204
+
205
+ test('Digest is 16-char hex string', () => {
206
+ const runtime = createRuntime({ seed: 'format-test' });
207
+ const digest = runtime.digest();
208
+ const isValidFormat = /^[0-9a-f]{16}$/.test(digest);
209
+ if (!isValidFormat) {
210
+ console.log(` Digest format invalid: "${digest}"`);
211
+ }
212
+ return isValidFormat;
213
+ });
214
+
215
+ console.log();
216
+ console.log('TEST GROUP 4: PRNG Determinism');
217
+ console.log('─'.repeat(60));
218
+
219
+ test('Same seed produces identical random sequence', () => {
220
+ const seq1: number[] = [];
221
+ const seq2: number[] = [];
222
+
223
+ const runtime1 = createRuntime({ seed: 'prng-test' });
224
+ const runtime2 = createRuntime({ seed: 'prng-test' });
225
+
226
+ for (let i = 0; i < 10; i++) {
227
+ seq1.push(runtime1.random());
228
+ seq2.push(runtime2.random());
229
+ }
230
+
231
+ return seq1.every((v, i) => v === seq2[i]);
232
+ });
233
+
234
+ test('Different seeds produce different sequences', () => {
235
+ const runtime1 = createRuntime({ seed: 'seed-x' });
236
+ const runtime2 = createRuntime({ seed: 'seed-y' });
237
+
238
+ return runtime1.random() !== runtime2.random();
239
+ });
240
+
241
+ test('Noise is deterministic for same inputs', () => {
242
+ const runtime1 = createRuntime({ seed: 'noise-test' });
243
+ const runtime2 = createRuntime({ seed: 'noise-test' });
244
+
245
+ const n1 = runtime1.noise(1.5, 2.5, 3.5);
246
+ const n2 = runtime2.noise(1.5, 2.5, 3.5);
247
+
248
+ return n1 === n2;
249
+ });
250
+
251
+ console.log();
252
+ console.log('TEST GROUP 5: Known Digest Values');
253
+ console.log('─'.repeat(60));
254
+
255
+ const knownConfig = { seed: 'known-digest-oracle', vars: [50, 50, 50, 50, 50, 50, 50, 50, 50, 50], mode: 'static' as const };
256
+ const knownRuntime = createRuntime(knownConfig);
257
+ const oracleDigest = knownRuntime.digest();
258
+ console.log(`Oracle digest for cross-env verification: ${oracleDigest}`);
259
+
260
+ test('Oracle digest format valid', () => {
261
+ return /^[0-9a-f]{16}$/.test(oracleDigest);
262
+ });
263
+
264
+ console.log();
265
+ console.log('═'.repeat(60));
266
+ console.log(`RESULTS: ${passCount} passed, ${failCount} failed`);
267
+ console.log('═'.repeat(60));
268
+
269
+ if (failCount > 0) {
270
+ console.log('❌ PREFLIGHT FAILED - DO NOT SHIP');
271
+ process.exit(1);
272
+ } else {
273
+ console.log('✅ PREFLIGHT PASSED - READY TO SHIP');
274
+ process.exit(0);
275
+ }
@@ -0,0 +1,151 @@
1
+ /**
2
+ * @nexart/codemode-sdk — Verification Example
3
+ *
4
+ * Demonstrates determinism verification and strict mode error handling.
5
+ *
6
+ * Run: npm run example:verify
7
+ */
8
+
9
+ import { createRuntime } from '../runtime';
10
+
11
+ console.log('╔══════════════════════════════════════════════════════════════╗');
12
+ console.log('║ NexArt Code Mode SDK — Verification Example ║');
13
+ console.log('╚══════════════════════════════════════════════════════════════╝');
14
+ console.log();
15
+
16
+ function generateRandomSequence(seed: string | number, vars: number[], count: number): number[] {
17
+ const runtime = createRuntime({ seed, vars, strict: true });
18
+ const values: number[] = [];
19
+ for (let i = 0; i < count; i++) {
20
+ values.push(runtime.random());
21
+ }
22
+ return values;
23
+ }
24
+
25
+ console.log('TEST 1: Same seed + vars = same output');
26
+ console.log('─'.repeat(50));
27
+
28
+ const seq1 = generateRandomSequence('test-seed', [50, 25], 5);
29
+ const seq2 = generateRandomSequence('test-seed', [50, 25], 5);
30
+
31
+ console.log('Run 1:', seq1.map(v => v.toFixed(6)).join(', '));
32
+ console.log('Run 2:', seq2.map(v => v.toFixed(6)).join(', '));
33
+
34
+ const identical = seq1.every((v, i) => v === seq2[i]);
35
+ console.log(`Result: ${identical ? '✅ PASS' : '❌ FAIL'} — sequences are ${identical ? 'identical' : 'different'}`);
36
+ console.log();
37
+
38
+ console.log('TEST 2: Same seed + vars = same digest');
39
+ console.log('─'.repeat(50));
40
+
41
+ const runtime1 = createRuntime({ seed: 'digest-test', vars: [10, 20, 30] });
42
+ const runtime2 = createRuntime({ seed: 'digest-test', vars: [10, 20, 30] });
43
+
44
+ const digest1 = runtime1.digest();
45
+ const digest2 = runtime2.digest();
46
+
47
+ console.log('Digest 1:', digest1);
48
+ console.log('Digest 2:', digest2);
49
+
50
+ const digestsMatch = digest1 === digest2;
51
+ console.log(`Result: ${digestsMatch ? '✅ PASS' : '❌ FAIL'} — digests are ${digestsMatch ? 'identical' : 'different'}`);
52
+ console.log();
53
+
54
+ console.log('TEST 3: Different vars = different digest');
55
+ console.log('─'.repeat(50));
56
+
57
+ const runtime3 = createRuntime({ seed: 'digest-test', vars: [10, 20, 30] });
58
+ const runtime4 = createRuntime({ seed: 'digest-test', vars: [10, 20, 31] });
59
+
60
+ const digest3 = runtime3.digest();
61
+ const digest4 = runtime4.digest();
62
+
63
+ console.log('Digest (vars [10,20,30]):', digest3);
64
+ console.log('Digest (vars [10,20,31]):', digest4);
65
+
66
+ const digestsDiffer = digest3 !== digest4;
67
+ console.log(`Result: ${digestsDiffer ? '✅ PASS' : '❌ FAIL'} — digests are ${digestsDiffer ? 'different' : 'identical'}`);
68
+ console.log();
69
+
70
+ console.log('TEST 4: Strict mode blocks Math.random');
71
+ console.log('─'.repeat(50));
72
+
73
+ const strictRuntime = createRuntime({ seed: 12345, strict: true });
74
+
75
+ let strictErrorCaught = false;
76
+ let errorMessage = '';
77
+
78
+ try {
79
+ strictRuntime.run(() => {
80
+ return Math.random();
81
+ });
82
+ } catch (error: any) {
83
+ strictErrorCaught = true;
84
+ errorMessage = error.message;
85
+ }
86
+
87
+ console.log('Called Math.random() in strict run...');
88
+ console.log(`Error caught: ${strictErrorCaught}`);
89
+ if (strictErrorCaught) {
90
+ console.log(`Error message: "${errorMessage}"`);
91
+ }
92
+
93
+ const expectedMessage = 'NEXART_STRICT: Non-deterministic API used: Math.random. Use runtime.random() instead.';
94
+ const correctError = errorMessage === expectedMessage;
95
+ console.log(`Result: ${strictErrorCaught && correctError ? '✅ PASS' : '❌ FAIL'} — strict mode ${strictErrorCaught ? 'blocked' : 'did not block'} Math.random`);
96
+ console.log();
97
+
98
+ console.log('TEST 5: Strict mode blocks Date.now');
99
+ console.log('─'.repeat(50));
100
+
101
+ let dateErrorCaught = false;
102
+ let dateErrorMessage = '';
103
+
104
+ try {
105
+ strictRuntime.run(() => {
106
+ return Date.now();
107
+ });
108
+ } catch (error: any) {
109
+ dateErrorCaught = true;
110
+ dateErrorMessage = error.message;
111
+ }
112
+
113
+ console.log('Called Date.now() in strict run...');
114
+ console.log(`Error caught: ${dateErrorCaught}`);
115
+ if (dateErrorCaught) {
116
+ console.log(`Error message: "${dateErrorMessage}"`);
117
+ }
118
+
119
+ const expectedDateMessage = 'NEXART_STRICT: Non-deterministic API used: Date.now. Pass time as an input or use deterministic counters.';
120
+ const correctDateError = dateErrorMessage === expectedDateMessage;
121
+ console.log(`Result: ${dateErrorCaught && correctDateError ? '✅ PASS' : '❌ FAIL'} — strict mode ${dateErrorCaught ? 'blocked' : 'did not block'} Date.now`);
122
+ console.log();
123
+
124
+ console.log('TEST 6: Non-strict mode allows Math.random');
125
+ console.log('─'.repeat(50));
126
+
127
+ const nonStrictRuntime = createRuntime({ seed: 12345, strict: false });
128
+
129
+ let nonStrictResult: number | null = null;
130
+ let nonStrictError = false;
131
+
132
+ try {
133
+ nonStrictResult = nonStrictRuntime.run(() => {
134
+ return Math.random();
135
+ });
136
+ } catch {
137
+ nonStrictError = true;
138
+ }
139
+
140
+ console.log('Called Math.random() in non-strict run...');
141
+ console.log(`Error thrown: ${nonStrictError}`);
142
+ console.log(`Result value: ${nonStrictResult}`);
143
+ console.log(`Result: ${!nonStrictError && nonStrictResult !== null ? '✅ PASS' : '❌ FAIL'} — non-strict mode ${!nonStrictError ? 'allowed' : 'blocked'} Math.random`);
144
+ console.log();
145
+
146
+ const allPassed = identical && digestsMatch && digestsDiffer && strictErrorCaught && correctError && dateErrorCaught && correctDateError && !nonStrictError;
147
+ console.log('═'.repeat(50));
148
+ console.log(allPassed ? '✅ All verification tests passed!' : '❌ Some tests failed');
149
+ console.log('═'.repeat(50));
150
+
151
+ process.exit(allPassed ? 0 : 1);
package/package.json CHANGED
@@ -1,27 +1,53 @@
1
1
  {
2
2
  "name": "@nexart/codemode-sdk",
3
- "version": "1.6.0",
4
- "description": "NexArt Code Mode SDK - Canonical execution engine for deterministic generative art",
3
+ "version": "1.8.0",
4
+ "description": "NexArt Code Mode SDK - Deterministic, reproducible, verifiable generative art runtime. Agent-first design for AI coding assistants.",
5
5
  "type": "module",
6
- "main": "./dist/core-index.js",
7
- "types": "./dist/core-index.d.ts",
6
+ "main": "./dist/entry/browser.js",
7
+ "types": "./dist/entry/browser.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
+ "browser": {
11
+ "types": "./dist/entry/browser.d.ts",
12
+ "import": "./dist/entry/browser.js"
13
+ },
14
+ "node": {
15
+ "types": "./dist/entry/node.d.ts",
16
+ "import": "./dist/entry/node.js"
17
+ },
18
+ "default": {
19
+ "types": "./dist/entry/browser.d.ts",
20
+ "import": "./dist/entry/browser.js"
21
+ }
22
+ },
23
+ "./browser": {
24
+ "types": "./dist/entry/browser.d.ts",
25
+ "import": "./dist/entry/browser.js"
26
+ },
27
+ "./node": {
28
+ "types": "./dist/entry/node.d.ts",
29
+ "import": "./dist/entry/node.js"
30
+ },
31
+ "./core": {
10
32
  "types": "./dist/core-index.d.ts",
11
33
  "import": "./dist/core-index.js"
12
34
  }
13
35
  },
14
36
  "files": [
15
37
  "dist",
38
+ "examples",
16
39
  "README.md",
17
40
  "CHANGELOG.md",
18
41
  "CODE_MODE_PROTOCOL.md",
19
42
  "LICENSE.md",
43
+ "LICENSING.md",
20
44
  "builder.manifest.schema.json"
21
45
  ],
22
46
  "scripts": {
23
47
  "build": "tsc",
24
48
  "test": "npx tsx smoke-test.ts",
49
+ "example:basic": "npx tsx examples/basic.ts",
50
+ "example:verify": "npx tsx examples/verify.ts",
25
51
  "prepublishOnly": "npm run build && npm run test"
26
52
  },
27
53
  "keywords": [
@@ -30,7 +56,21 @@
30
56
  "nft",
31
57
  "p5js",
32
58
  "deterministic",
33
- "codemode"
59
+ "reproducible",
60
+ "verifiable",
61
+ "replay",
62
+ "canonical",
63
+ "simulation",
64
+ "procedural",
65
+ "generative",
66
+ "seed",
67
+ "prng",
68
+ "noise",
69
+ "codemode",
70
+ "browser",
71
+ "node",
72
+ "ai-agent",
73
+ "strict-mode"
34
74
  ],
35
75
  "author": "NexArt",
36
76
  "license": "MIT",