@vib3code/sdk 2.0.3-canary.6f35b4c → 2.0.3-canary.74aebb4
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/DOCS/EXPANSION_DESIGN.md +977 -0
- package/DOCS/EXPANSION_DESIGN_ULTRA.md +387 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +2 -2
- package/DOCS/OPTIMIZATION_PLAN_MATH.md +118 -0
- package/DOCS/SYSTEM_INVENTORY.md +2 -2
- package/DOCS/WEBGPU_STATUS.md +119 -38
- package/DOCS/archive/WEBGPU_STATUS_2026-02-15_STALE.md +38 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-15.md +142 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +108 -0
- package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +308 -0
- package/docs/webgpu-live.html +1 -1
- package/package.json +10 -1
- package/src/agent/index.js +1 -3
- package/src/agent/mcp/MCPServer.js +542 -188
- package/src/agent/mcp/index.js +1 -1
- package/src/agent/mcp/tools.js +132 -32
- package/src/cli/index.js +374 -44
- package/src/core/VIB3Engine.js +55 -3
- package/src/core/index.js +18 -0
- package/src/core/renderers/FacetedRendererAdapter.js +10 -9
- package/src/core/renderers/HolographicRendererAdapter.js +11 -7
- package/src/core/renderers/QuantumRendererAdapter.js +11 -7
- package/src/creative/index.js +11 -0
- package/src/experimental/GameLoop.js +72 -0
- package/src/experimental/LatticePhysics.js +100 -0
- package/src/experimental/LiveDirector.js +143 -0
- package/src/experimental/PlayerController4D.js +154 -0
- package/src/experimental/VIB3Actor.js +138 -0
- package/src/experimental/VIB3Compositor.js +117 -0
- package/src/experimental/VIB3Link.js +122 -0
- package/src/experimental/VIB3Orchestrator.js +146 -0
- package/src/experimental/VIB3Universe.js +109 -0
- package/src/experimental/demos/CrystalLabyrinth.js +202 -0
- package/src/export/index.js +11 -1
- package/src/faceted/FacetedSystem.js +27 -10
- package/src/games/glyph-war/GlyphWarVisualizer.js +641 -0
- package/src/geometry/generators/Crystal.js +2 -2
- package/src/holograms/HolographicVisualizer.js +58 -89
- package/src/holograms/RealHolographicSystem.js +126 -31
- package/src/math/Mat4x4.js +192 -19
- package/src/math/Rotor4D.js +93 -39
- package/src/math/Vec4.js +119 -78
- package/src/math/index.js +7 -7
- package/src/quantum/QuantumVisualizer.js +24 -20
- package/src/reactivity/index.js +3 -5
- package/src/render/LayerPresetManager.js +372 -0
- package/src/render/LayerReactivityBridge.js +344 -0
- package/src/render/LayerRelationshipGraph.js +610 -0
- package/src/render/MultiCanvasBridge.js +148 -25
- package/src/render/ShaderLoader.js +38 -0
- package/src/render/ShaderProgram.js +4 -4
- package/src/render/UnifiedRenderBridge.js +1 -1
- package/src/render/backends/WebGPUBackend.js +8 -4
- package/src/render/index.js +27 -2
- package/src/scene/index.js +4 -4
- package/src/shaders/common/geometry24.glsl +65 -0
- package/src/shaders/common/geometry24.wgsl +54 -0
- package/src/shaders/common/rotation4d.glsl +4 -4
- package/src/shaders/common/rotation4d.wgsl +2 -2
- package/src/shaders/common/uniforms.wgsl +15 -8
- package/src/shaders/faceted/faceted.frag.wgsl +19 -6
- package/src/shaders/holographic/holographic.frag.wgsl +7 -5
- package/src/shaders/quantum/quantum.frag.wgsl +7 -5
- package/src/testing/ParallelTestFramework.js +2 -2
- package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +2 -2
- package/src/viewer/GalleryUI.js +17 -0
- package/src/viewer/ViewerPortal.js +2 -2
- package/tools/shader-sync-verify.js +6 -4
- package/types/adaptive-sdk.d.ts +204 -5
- package/types/agent/cli.d.ts +78 -0
- package/types/agent/index.d.ts +18 -0
- package/types/agent/mcp.d.ts +87 -0
- package/types/agent/telemetry.d.ts +190 -0
- package/types/core/VIB3Engine.d.ts +26 -0
- package/types/core/index.d.ts +261 -0
- package/types/creative/AestheticMapper.d.ts +72 -0
- package/types/creative/ChoreographyPlayer.d.ts +96 -0
- package/types/creative/index.d.ts +17 -0
- package/types/export/index.d.ts +243 -0
- package/types/geometry/index.d.ts +164 -0
- package/types/math/index.d.ts +214 -0
- package/types/render/LayerPresetManager.d.ts +78 -0
- package/types/render/LayerReactivityBridge.d.ts +85 -0
- package/types/render/LayerRelationshipGraph.d.ts +174 -0
- package/types/render/index.d.ts +3 -0
- package/types/scene/index.d.ts +204 -0
- package/types/systems/index.d.ts +244 -0
- package/types/variations/index.d.ts +62 -0
- package/types/viewer/index.d.ts +225 -0
package/src/cli/index.js
CHANGED
|
@@ -172,7 +172,8 @@ function showHelp(isJson) {
|
|
|
172
172
|
description: 'VIB3+ 4D Visualization Engine CLI',
|
|
173
173
|
usage: `${CLI_NAME} <command> [options]`,
|
|
174
174
|
commands: {
|
|
175
|
-
|
|
175
|
+
init: 'Scaffold a new VIB3+ project (--template vanilla|react|vue|svelte)',
|
|
176
|
+
create: 'Create a new 4D visualization (--describe, --preset, --color, --hue, --XW, etc.)',
|
|
176
177
|
state: 'Get current engine state',
|
|
177
178
|
set: 'Set parameters (rotation, visual)',
|
|
178
179
|
geometry: 'Change or list geometries',
|
|
@@ -190,7 +191,14 @@ function showHelp(isJson) {
|
|
|
190
191
|
'--verbose': 'Verbose output'
|
|
191
192
|
},
|
|
192
193
|
examples: [
|
|
194
|
+
`${CLI_NAME} init my-app`,
|
|
195
|
+
`${CLI_NAME} init my-app --template react`,
|
|
196
|
+
`${CLI_NAME} init my-app --template vue`,
|
|
197
|
+
`${CLI_NAME} init my-app --template svelte`,
|
|
193
198
|
`${CLI_NAME} create --system quantum --geometry 8 --json`,
|
|
199
|
+
`${CLI_NAME} create --describe "serene ocean deep organic"`,
|
|
200
|
+
`${CLI_NAME} create --system holographic --preset energetic --color neon`,
|
|
201
|
+
`${CLI_NAME} create --system faceted --geometry 16 --XW 0.8 --YW 0.5 --hue 200`,
|
|
194
202
|
`${CLI_NAME} set rotation --XW 1.5 --YW 0.5`,
|
|
195
203
|
`${CLI_NAME} set visual --hue 200 --chaos 0.3`,
|
|
196
204
|
`${CLI_NAME} geometry list --core-type hypersphere`,
|
|
@@ -224,15 +232,84 @@ function showVersion(isJson) {
|
|
|
224
232
|
|
|
225
233
|
/**
|
|
226
234
|
* Handle 'create' command
|
|
235
|
+
*
|
|
236
|
+
* Supports full creative parameter control:
|
|
237
|
+
* vib3 create --system quantum --geometry 11 --hue 200 --chaos 0.3
|
|
238
|
+
* vib3 create --system holographic --preset energetic
|
|
239
|
+
* vib3 create --describe "serene ocean deep organic"
|
|
240
|
+
* vib3 create --system faceted --geometry 16 --XW 0.8 --YW 0.5 --speed 0.6
|
|
227
241
|
*/
|
|
228
242
|
async function handleCreate(parsed) {
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
243
|
+
const opts = parsed.options;
|
|
244
|
+
|
|
245
|
+
// Natural language description path — uses AestheticMapper
|
|
246
|
+
if (opts.describe || opts.description) {
|
|
247
|
+
const description = opts.describe || opts.description;
|
|
248
|
+
return await mcpServer.handleToolCall('design_from_description', {
|
|
249
|
+
description,
|
|
250
|
+
apply: true
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Step 1: Create the visualization scene
|
|
255
|
+
const createArgs = {
|
|
256
|
+
system: opts.system || 'quantum',
|
|
257
|
+
geometry_index: parseInt(opts.geometry || '0'),
|
|
258
|
+
projection: opts.projection || 'perspective'
|
|
233
259
|
};
|
|
260
|
+
const createResult = await mcpServer.handleToolCall('create_4d_visualization', createArgs);
|
|
261
|
+
|
|
262
|
+
// Step 2: Apply rotation if any 6D rotation flags provided
|
|
263
|
+
const rotationPlanes = ['XY', 'XZ', 'YZ', 'XW', 'YW', 'ZW'];
|
|
264
|
+
const rotationArgs = {};
|
|
265
|
+
let hasRotation = false;
|
|
266
|
+
for (const plane of rotationPlanes) {
|
|
267
|
+
if (opts[plane] !== undefined) {
|
|
268
|
+
rotationArgs[plane] = parseFloat(opts[plane]);
|
|
269
|
+
hasRotation = true;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (hasRotation) {
|
|
273
|
+
await mcpServer.handleToolCall('set_rotation', rotationArgs);
|
|
274
|
+
}
|
|
234
275
|
|
|
235
|
-
|
|
276
|
+
// Step 3: Apply visual parameters if any provided
|
|
277
|
+
const visualKeys = ['hue', 'saturation', 'intensity', 'speed', 'chaos', 'morphFactor', 'gridDensity', 'dimension'];
|
|
278
|
+
const visualArgs = {};
|
|
279
|
+
let hasVisual = false;
|
|
280
|
+
for (const key of visualKeys) {
|
|
281
|
+
if (opts[key] !== undefined) {
|
|
282
|
+
visualArgs[key] = key === 'hue' ? parseInt(opts[key]) : parseFloat(opts[key]);
|
|
283
|
+
hasVisual = true;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (hasVisual) {
|
|
287
|
+
await mcpServer.handleToolCall('set_visual_parameters', visualArgs);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Step 4: Apply behavior preset if specified (ambient, reactive, immersive, energetic, calm, cinematic)
|
|
291
|
+
if (opts.preset) {
|
|
292
|
+
const presetDefaults = {
|
|
293
|
+
ambient: { speed: 0.3, chaos: 0.1 },
|
|
294
|
+
reactive: { speed: 1.0, chaos: 0.3 },
|
|
295
|
+
immersive: { speed: 0.8, chaos: 0.15 },
|
|
296
|
+
energetic: { speed: 2.5, chaos: 0.8 },
|
|
297
|
+
calm: { speed: 0.2, chaos: 0.05 },
|
|
298
|
+
cinematic: { speed: 0.5, chaos: 0.2 }
|
|
299
|
+
};
|
|
300
|
+
const presetParams = presetDefaults[opts.preset];
|
|
301
|
+
if (presetParams) {
|
|
302
|
+
await mcpServer.handleToolCall('set_visual_parameters', presetParams);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Step 5: Apply color preset if specified (ocean, neon, galaxy, etc.)
|
|
307
|
+
if (opts.color || opts.colorPreset) {
|
|
308
|
+
const colorName = opts.color || opts.colorPreset;
|
|
309
|
+
await mcpServer.handleToolCall('apply_color_preset', { preset: colorName });
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return createResult;
|
|
236
313
|
}
|
|
237
314
|
|
|
238
315
|
/**
|
|
@@ -578,12 +655,28 @@ async function main() {
|
|
|
578
655
|
|
|
579
656
|
/**
|
|
580
657
|
* Handle init command — scaffold a new VIB3+ project
|
|
658
|
+
* Supports --template vanilla|react|vue|svelte
|
|
581
659
|
*/
|
|
582
660
|
async function handleInit(parsed, startTime) {
|
|
583
661
|
const { writeFileSync, mkdirSync, existsSync } = await import('node:fs');
|
|
584
662
|
const { join } = await import('node:path');
|
|
585
663
|
|
|
586
|
-
const projectName = parsed.positional[0] || 'my-vib3-app';
|
|
664
|
+
const projectName = parsed.subcommand || parsed.positional[0] || 'my-vib3-app';
|
|
665
|
+
const template = parsed.options.template || parsed.options.t || 'vanilla';
|
|
666
|
+
const validTemplates = ['vanilla', 'react', 'vue', 'svelte'];
|
|
667
|
+
|
|
668
|
+
if (!validTemplates.includes(template)) {
|
|
669
|
+
return wrapResponse('init', {
|
|
670
|
+
error: {
|
|
671
|
+
type: 'ValidationError',
|
|
672
|
+
code: 'INVALID_TEMPLATE',
|
|
673
|
+
message: `Unknown template: ${template}`,
|
|
674
|
+
valid_options: validTemplates,
|
|
675
|
+
suggestion: `Use --template ${validTemplates.join('|')}`
|
|
676
|
+
}
|
|
677
|
+
}, false, performance.now() - startTime);
|
|
678
|
+
}
|
|
679
|
+
|
|
587
680
|
const projectDir = join(process.cwd(), projectName);
|
|
588
681
|
|
|
589
682
|
if (existsSync(projectDir)) {
|
|
@@ -599,25 +692,277 @@ async function handleInit(parsed, startTime) {
|
|
|
599
692
|
|
|
600
693
|
mkdirSync(projectDir, { recursive: true });
|
|
601
694
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
build: 'npx vite build'
|
|
610
|
-
},
|
|
611
|
-
dependencies: {
|
|
612
|
-
'@vib3code/sdk': '^2.0.0'
|
|
613
|
-
},
|
|
614
|
-
devDependencies: {
|
|
615
|
-
vite: '^5.3.0'
|
|
695
|
+
const files = getTemplateFiles(template, projectName);
|
|
696
|
+
|
|
697
|
+
for (const [filename, content] of Object.entries(files)) {
|
|
698
|
+
const filepath = join(projectDir, filename);
|
|
699
|
+
const dir = join(projectDir, filename.split('/').slice(0, -1).join('/'));
|
|
700
|
+
if (dir !== projectDir) {
|
|
701
|
+
mkdirSync(dir, { recursive: true });
|
|
616
702
|
}
|
|
617
|
-
|
|
703
|
+
writeFileSync(filepath, content);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
const fileNames = Object.keys(files);
|
|
707
|
+
const tree = fileNames.map((f, i) =>
|
|
708
|
+
` ${i === fileNames.length - 1 ? '└── ' : '├── '}${f}`
|
|
709
|
+
).join('\n');
|
|
710
|
+
|
|
711
|
+
console.log(`\n Created ${projectName}/ (${template} template)`);
|
|
712
|
+
console.log(tree);
|
|
713
|
+
console.log(`\n Next steps:`);
|
|
714
|
+
console.log(` cd ${projectName}`);
|
|
715
|
+
console.log(' npm install');
|
|
716
|
+
console.log(' npm run dev\n');
|
|
717
|
+
|
|
718
|
+
return wrapResponse('init', {
|
|
719
|
+
project: projectName,
|
|
720
|
+
template,
|
|
721
|
+
files: fileNames,
|
|
722
|
+
next_steps: [`cd ${projectName}`, 'npm install', 'npm run dev']
|
|
723
|
+
}, true, performance.now() - startTime);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* Generate template files based on framework choice
|
|
728
|
+
*/
|
|
729
|
+
function getTemplateFiles(template, projectName) {
|
|
730
|
+
const sdkDep = { '@vib3code/sdk': '^2.0.0' };
|
|
731
|
+
const viteDep = { vite: '^5.3.0' };
|
|
732
|
+
|
|
733
|
+
switch (template) {
|
|
734
|
+
case 'react':
|
|
735
|
+
return {
|
|
736
|
+
'package.json': JSON.stringify({
|
|
737
|
+
name: projectName,
|
|
738
|
+
version: '0.1.0',
|
|
739
|
+
type: 'module',
|
|
740
|
+
scripts: { dev: 'npx vite --open', build: 'npx vite build' },
|
|
741
|
+
dependencies: { ...sdkDep, react: '^18.3.0', 'react-dom': '^18.3.0' },
|
|
742
|
+
devDependencies: { ...viteDep, '@vitejs/plugin-react': '^4.3.0' }
|
|
743
|
+
}, null, 2) + '\n',
|
|
744
|
+
'vite.config.js': `import { defineConfig } from 'vite';
|
|
745
|
+
import react from '@vitejs/plugin-react';
|
|
746
|
+
export default defineConfig({ plugins: [react()] });
|
|
747
|
+
`,
|
|
748
|
+
'index.html': `<!DOCTYPE html>
|
|
749
|
+
<html lang="en">
|
|
750
|
+
<head>
|
|
751
|
+
<meta charset="utf-8">
|
|
752
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
753
|
+
<title>${projectName}</title>
|
|
754
|
+
</head>
|
|
755
|
+
<body>
|
|
756
|
+
<div id="root"></div>
|
|
757
|
+
<script type="module" src="/src/main.jsx"></script>
|
|
758
|
+
</body>
|
|
759
|
+
</html>
|
|
760
|
+
`,
|
|
761
|
+
'src/main.jsx': `import React from 'react';
|
|
762
|
+
import ReactDOM from 'react-dom/client';
|
|
763
|
+
import App from './App.jsx';
|
|
764
|
+
|
|
765
|
+
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
|
|
766
|
+
`,
|
|
767
|
+
'src/App.jsx': `import React, { useRef, useEffect, useState } from 'react';
|
|
768
|
+
import { VIB3Engine } from '@vib3code/sdk/core';
|
|
769
|
+
|
|
770
|
+
export default function App() {
|
|
771
|
+
const engineRef = useRef(null);
|
|
772
|
+
const [system, setSystem] = useState('quantum');
|
|
773
|
+
const [geometry, setGeometry] = useState(0);
|
|
774
|
+
const [hue, setHue] = useState(200);
|
|
775
|
+
|
|
776
|
+
useEffect(() => {
|
|
777
|
+
const engine = new VIB3Engine();
|
|
778
|
+
engineRef.current = engine;
|
|
779
|
+
engine.initialize().then(() => engine.switchSystem(system));
|
|
780
|
+
return () => engine.destroy();
|
|
781
|
+
}, []);
|
|
782
|
+
|
|
783
|
+
useEffect(() => {
|
|
784
|
+
engineRef.current?.switchSystem(system);
|
|
785
|
+
}, [system]);
|
|
786
|
+
|
|
787
|
+
useEffect(() => {
|
|
788
|
+
engineRef.current?.setParameter('geometry', geometry);
|
|
789
|
+
}, [geometry]);
|
|
790
|
+
|
|
791
|
+
useEffect(() => {
|
|
792
|
+
engineRef.current?.setParameter('hue', hue);
|
|
793
|
+
}, [hue]);
|
|
794
|
+
|
|
795
|
+
return (
|
|
796
|
+
<div style={{ margin: 0, background: '#07070f', minHeight: '100vh' }}>
|
|
797
|
+
<div style={{ position: 'fixed', top: 12, left: 12, zIndex: 10, font: '13px monospace', color: '#0fc', display: 'flex', gap: 12 }}>
|
|
798
|
+
<label>System:
|
|
799
|
+
<select value={system} onChange={e => setSystem(e.target.value)} style={{ marginLeft: 6 }}>
|
|
800
|
+
<option>quantum</option>
|
|
801
|
+
<option>faceted</option>
|
|
802
|
+
<option>holographic</option>
|
|
803
|
+
</select>
|
|
804
|
+
</label>
|
|
805
|
+
<label>Geometry: <input type="range" min="0" max="23" value={geometry} onChange={e => setGeometry(+e.target.value)} /></label>
|
|
806
|
+
<label>Hue: <input type="range" min="0" max="360" value={hue} onChange={e => setHue(+e.target.value)} /></label>
|
|
807
|
+
</div>
|
|
808
|
+
</div>
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
`
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
case 'vue':
|
|
815
|
+
return {
|
|
816
|
+
'package.json': JSON.stringify({
|
|
817
|
+
name: projectName,
|
|
818
|
+
version: '0.1.0',
|
|
819
|
+
type: 'module',
|
|
820
|
+
scripts: { dev: 'npx vite --open', build: 'npx vite build' },
|
|
821
|
+
dependencies: { ...sdkDep, vue: '^3.4.0' },
|
|
822
|
+
devDependencies: { ...viteDep, '@vitejs/plugin-vue': '^5.1.0' }
|
|
823
|
+
}, null, 2) + '\n',
|
|
824
|
+
'vite.config.js': `import { defineConfig } from 'vite';
|
|
825
|
+
import vue from '@vitejs/plugin-vue';
|
|
826
|
+
export default defineConfig({ plugins: [vue()] });
|
|
827
|
+
`,
|
|
828
|
+
'index.html': `<!DOCTYPE html>
|
|
829
|
+
<html lang="en">
|
|
830
|
+
<head>
|
|
831
|
+
<meta charset="utf-8">
|
|
832
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
833
|
+
<title>${projectName}</title>
|
|
834
|
+
</head>
|
|
835
|
+
<body>
|
|
836
|
+
<div id="app"></div>
|
|
837
|
+
<script type="module" src="/src/main.js"></script>
|
|
838
|
+
</body>
|
|
839
|
+
</html>
|
|
840
|
+
`,
|
|
841
|
+
'src/main.js': `import { createApp } from 'vue';
|
|
842
|
+
import App from './App.vue';
|
|
843
|
+
createApp(App).mount('#app');
|
|
844
|
+
`,
|
|
845
|
+
'src/App.vue': `<script setup>
|
|
846
|
+
import { ref, onMounted, onUnmounted, watch } from 'vue';
|
|
847
|
+
import { VIB3Engine } from '@vib3code/sdk/core';
|
|
848
|
+
|
|
849
|
+
const engine = ref(null);
|
|
850
|
+
const system = ref('quantum');
|
|
851
|
+
const geometry = ref(0);
|
|
852
|
+
const hue = ref(200);
|
|
853
|
+
|
|
854
|
+
onMounted(async () => {
|
|
855
|
+
engine.value = new VIB3Engine();
|
|
856
|
+
await engine.value.initialize();
|
|
857
|
+
await engine.value.switchSystem(system.value);
|
|
858
|
+
});
|
|
618
859
|
|
|
619
|
-
|
|
620
|
-
|
|
860
|
+
onUnmounted(() => engine.value?.destroy());
|
|
861
|
+
|
|
862
|
+
watch(system, (val) => engine.value?.switchSystem(val));
|
|
863
|
+
watch(geometry, (val) => engine.value?.setParameter('geometry', val));
|
|
864
|
+
watch(hue, (val) => engine.value?.setParameter('hue', val));
|
|
865
|
+
</script>
|
|
866
|
+
|
|
867
|
+
<template>
|
|
868
|
+
<div style="margin: 0; background: #07070f; min-height: 100vh">
|
|
869
|
+
<div style="position: fixed; top: 12px; left: 12px; z-index: 10; font: 13px monospace; color: #0fc; display: flex; gap: 12px">
|
|
870
|
+
<label>System:
|
|
871
|
+
<select v-model="system" style="margin-left: 6px">
|
|
872
|
+
<option>quantum</option>
|
|
873
|
+
<option>faceted</option>
|
|
874
|
+
<option>holographic</option>
|
|
875
|
+
</select>
|
|
876
|
+
</label>
|
|
877
|
+
<label>Geometry: <input type="range" min="0" max="23" v-model.number="geometry" /></label>
|
|
878
|
+
<label>Hue: <input type="range" min="0" max="360" v-model.number="hue" /></label>
|
|
879
|
+
</div>
|
|
880
|
+
</div>
|
|
881
|
+
</template>
|
|
882
|
+
`
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
case 'svelte':
|
|
886
|
+
return {
|
|
887
|
+
'package.json': JSON.stringify({
|
|
888
|
+
name: projectName,
|
|
889
|
+
version: '0.1.0',
|
|
890
|
+
type: 'module',
|
|
891
|
+
scripts: { dev: 'npx vite --open', build: 'npx vite build' },
|
|
892
|
+
dependencies: sdkDep,
|
|
893
|
+
devDependencies: { ...viteDep, '@sveltejs/vite-plugin-svelte': '^3.2.0', svelte: '^4.2.0' }
|
|
894
|
+
}, null, 2) + '\n',
|
|
895
|
+
'vite.config.js': `import { defineConfig } from 'vite';
|
|
896
|
+
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
897
|
+
export default defineConfig({ plugins: [svelte()] });
|
|
898
|
+
`,
|
|
899
|
+
'index.html': `<!DOCTYPE html>
|
|
900
|
+
<html lang="en">
|
|
901
|
+
<head>
|
|
902
|
+
<meta charset="utf-8">
|
|
903
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
904
|
+
<title>${projectName}</title>
|
|
905
|
+
</head>
|
|
906
|
+
<body>
|
|
907
|
+
<div id="app"></div>
|
|
908
|
+
<script type="module" src="/src/main.js"></script>
|
|
909
|
+
</body>
|
|
910
|
+
</html>
|
|
911
|
+
`,
|
|
912
|
+
'src/main.js': `import App from './App.svelte';
|
|
913
|
+
const app = new App({ target: document.getElementById('app') });
|
|
914
|
+
export default app;
|
|
915
|
+
`,
|
|
916
|
+
'src/App.svelte': `<script>
|
|
917
|
+
import { onMount, onDestroy } from 'svelte';
|
|
918
|
+
import { VIB3Engine } from '@vib3code/sdk/core';
|
|
919
|
+
|
|
920
|
+
let engine = null;
|
|
921
|
+
let system = 'quantum';
|
|
922
|
+
let geometry = 0;
|
|
923
|
+
let hue = 200;
|
|
924
|
+
|
|
925
|
+
onMount(async () => {
|
|
926
|
+
engine = new VIB3Engine();
|
|
927
|
+
await engine.initialize();
|
|
928
|
+
await engine.switchSystem(system);
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
onDestroy(() => engine?.destroy());
|
|
932
|
+
|
|
933
|
+
$: engine?.switchSystem(system);
|
|
934
|
+
$: engine?.setParameter('geometry', geometry);
|
|
935
|
+
$: engine?.setParameter('hue', hue);
|
|
936
|
+
</script>
|
|
937
|
+
|
|
938
|
+
<div style="margin: 0; background: #07070f; min-height: 100vh">
|
|
939
|
+
<div style="position: fixed; top: 12px; left: 12px; z-index: 10; font: 13px monospace; color: #0fc; display: flex; gap: 12px">
|
|
940
|
+
<label>System:
|
|
941
|
+
<select bind:value={system} style="margin-left: 6px">
|
|
942
|
+
<option>quantum</option>
|
|
943
|
+
<option>faceted</option>
|
|
944
|
+
<option>holographic</option>
|
|
945
|
+
</select>
|
|
946
|
+
</label>
|
|
947
|
+
<label>Geometry: <input type="range" min="0" max="23" bind:value={geometry} /></label>
|
|
948
|
+
<label>Hue: <input type="range" min="0" max="360" bind:value={hue} /></label>
|
|
949
|
+
</div>
|
|
950
|
+
</div>
|
|
951
|
+
`
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
case 'vanilla':
|
|
955
|
+
default:
|
|
956
|
+
return {
|
|
957
|
+
'package.json': JSON.stringify({
|
|
958
|
+
name: projectName,
|
|
959
|
+
version: '0.1.0',
|
|
960
|
+
type: 'module',
|
|
961
|
+
scripts: { dev: 'npx vite --open', build: 'npx vite build' },
|
|
962
|
+
dependencies: sdkDep,
|
|
963
|
+
devDependencies: viteDep
|
|
964
|
+
}, null, 2) + '\n',
|
|
965
|
+
'index.html': `<!DOCTYPE html>
|
|
621
966
|
<html lang="en">
|
|
622
967
|
<head>
|
|
623
968
|
<meta charset="utf-8">
|
|
@@ -638,10 +983,8 @@ async function handleInit(parsed, startTime) {
|
|
|
638
983
|
<script type="module" src="main.js"></script>
|
|
639
984
|
</body>
|
|
640
985
|
</html>
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
// main.js
|
|
644
|
-
writeFileSync(join(projectDir, 'main.js'), `import { VIB3Engine } from '@vib3code/sdk/core';
|
|
986
|
+
`,
|
|
987
|
+
'main.js': `import { VIB3Engine } from '@vib3code/sdk/core';
|
|
645
988
|
|
|
646
989
|
const engine = new VIB3Engine();
|
|
647
990
|
await engine.initialize();
|
|
@@ -650,22 +993,9 @@ await engine.switchSystem('quantum');
|
|
|
650
993
|
document.getElementById('sys').addEventListener('change', (e) => engine.switchSystem(e.target.value));
|
|
651
994
|
document.getElementById('geo').addEventListener('input', (e) => engine.setParameter('geometry', +e.target.value));
|
|
652
995
|
document.getElementById('hue').addEventListener('input', (e) => engine.setParameter('hue', +e.target.value));
|
|
653
|
-
`
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
console.log(' ├── package.json');
|
|
657
|
-
console.log(' ├── index.html');
|
|
658
|
-
console.log(' └── main.js');
|
|
659
|
-
console.log(`\\n Next steps:`);
|
|
660
|
-
console.log(` cd ${projectName}`);
|
|
661
|
-
console.log(' npm install');
|
|
662
|
-
console.log(' npm run dev\\n');
|
|
663
|
-
|
|
664
|
-
return wrapResponse('init', {
|
|
665
|
-
project: projectName,
|
|
666
|
-
files: ['package.json', 'index.html', 'main.js'],
|
|
667
|
-
next_steps: [`cd ${projectName}`, 'npm install', 'npm run dev']
|
|
668
|
-
}, true, performance.now() - startTime);
|
|
996
|
+
`
|
|
997
|
+
};
|
|
998
|
+
}
|
|
669
999
|
}
|
|
670
1000
|
|
|
671
1001
|
// Run CLI
|
package/src/core/VIB3Engine.js
CHANGED
|
@@ -26,7 +26,7 @@ export class VIB3Engine {
|
|
|
26
26
|
*/
|
|
27
27
|
constructor(options = {}) {
|
|
28
28
|
this.activeSystem = null; // Only one system active at a time
|
|
29
|
-
this.currentSystemName = 'quantum';
|
|
29
|
+
this.currentSystemName = options.system || 'quantum';
|
|
30
30
|
this.parameters = new ParameterManager();
|
|
31
31
|
this.initialized = false;
|
|
32
32
|
this.canvasManager = null;
|
|
@@ -82,7 +82,11 @@ export class VIB3Engine {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
// Initialize starting system
|
|
85
|
-
await this.switchSystem(this.currentSystemName);
|
|
85
|
+
const systemOk = await this.switchSystem(this.currentSystemName);
|
|
86
|
+
if (!systemOk) {
|
|
87
|
+
console.error(`VIB3+ Engine: Failed to create initial system "${this.currentSystemName}"`);
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
86
90
|
|
|
87
91
|
// Sync base parameters to reactivity manager
|
|
88
92
|
this.reactivity.setBaseParameters(this.parameters.getAllParameters());
|
|
@@ -167,7 +171,7 @@ export class VIB3Engine {
|
|
|
167
171
|
}
|
|
168
172
|
}
|
|
169
173
|
|
|
170
|
-
const facetedSuccess = system.initialize();
|
|
174
|
+
const facetedSuccess = await system.initialize();
|
|
171
175
|
if (!facetedSuccess) {
|
|
172
176
|
throw new Error('Faceted system initialization failed');
|
|
173
177
|
}
|
|
@@ -273,6 +277,17 @@ export class VIB3Engine {
|
|
|
273
277
|
|
|
274
278
|
if (this.activeSystem && this.activeSystem.updateParameters) {
|
|
275
279
|
this.activeSystem.updateParameters(params);
|
|
280
|
+
} else if (this.debug && this.activeSystem && !this.activeSystem.updateParameters) {
|
|
281
|
+
console.warn('VIB3+ Engine [debug]: activeSystem missing updateParameters() method');
|
|
282
|
+
} else if (this.debug && !this.activeSystem) {
|
|
283
|
+
console.warn('VIB3+ Engine [debug]: updateCurrentSystemParameters() called with no activeSystem');
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Notify parameter change listeners
|
|
287
|
+
if (this._parameterListeners && this._parameterListeners.size > 0) {
|
|
288
|
+
for (const listener of this._parameterListeners) {
|
|
289
|
+
try { listener(params); } catch (_) { /* listener error */ }
|
|
290
|
+
}
|
|
276
291
|
}
|
|
277
292
|
}
|
|
278
293
|
|
|
@@ -632,6 +647,43 @@ export class VIB3Engine {
|
|
|
632
647
|
}
|
|
633
648
|
}
|
|
634
649
|
|
|
650
|
+
// ========================================================================
|
|
651
|
+
// Convenience Methods (dogfood feedback)
|
|
652
|
+
// ========================================================================
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Create a parameter update callback for use with creative modules.
|
|
656
|
+
* Returns (name, value) => void that calls setParameter internally.
|
|
657
|
+
* Eliminates boilerplate: `(name, value) => engine.setParameter(name, value)`.
|
|
658
|
+
* @returns {(name: string, value: number) => void}
|
|
659
|
+
*/
|
|
660
|
+
createParameterCallback() {
|
|
661
|
+
return (name, value) => this.setParameter(name, value);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Get current breath value from VitalitySystem (0-1).
|
|
666
|
+
* Avoids reaching into engine.vitality.getBreath() directly.
|
|
667
|
+
* @returns {number}
|
|
668
|
+
*/
|
|
669
|
+
getBreath() {
|
|
670
|
+
return this.vitality.getBreath();
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Register a listener for parameter changes.
|
|
675
|
+
* Callback receives the full parameter object after each change.
|
|
676
|
+
* @param {(params: object) => void} callback
|
|
677
|
+
* @returns {() => void} Unsubscribe function
|
|
678
|
+
*/
|
|
679
|
+
onParameterChange(callback) {
|
|
680
|
+
if (!this._parameterListeners) {
|
|
681
|
+
this._parameterListeners = new Set();
|
|
682
|
+
}
|
|
683
|
+
this._parameterListeners.add(callback);
|
|
684
|
+
return () => this._parameterListeners.delete(callback);
|
|
685
|
+
}
|
|
686
|
+
|
|
635
687
|
/**
|
|
636
688
|
* Destroy engine and clean up
|
|
637
689
|
*/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VIB3+ Core Module
|
|
3
|
+
* @module core
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { VIB3Engine } from './VIB3Engine.js';
|
|
7
|
+
export { CanvasManager } from './CanvasManager.js';
|
|
8
|
+
export { ParameterManager } from './Parameters.js';
|
|
9
|
+
export { ParameterMapper } from './ParameterMapper.js';
|
|
10
|
+
export { ErrorReporter } from './ErrorReporter.js';
|
|
11
|
+
export { VitalitySystem } from './VitalitySystem.js';
|
|
12
|
+
export { UnifiedResourceManager } from './UnifiedResourceManager.js';
|
|
13
|
+
export {
|
|
14
|
+
RendererContract,
|
|
15
|
+
RendererContractAdapter,
|
|
16
|
+
verifyRendererContract,
|
|
17
|
+
ResourceManagerContract
|
|
18
|
+
} from './RendererContracts.js';
|
|
@@ -8,18 +8,19 @@ export class FacetedRendererAdapter extends RendererContract {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
init(context = {}) {
|
|
11
|
-
|
|
12
|
-
if (!initialized) {
|
|
13
|
-
throw new Error('Faceted renderer failed to initialize.');
|
|
14
|
-
}
|
|
11
|
+
return this.system.init ? this.system.init(context) : true;
|
|
15
12
|
}
|
|
16
13
|
|
|
17
|
-
resize() {
|
|
18
|
-
this.system.
|
|
14
|
+
resize(width, height, pixelRatio = 1) {
|
|
15
|
+
if (this.system.resize) {
|
|
16
|
+
this.system.resize(width, height, pixelRatio);
|
|
17
|
+
}
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
render() {
|
|
22
|
-
this.system.
|
|
20
|
+
render(frameState) {
|
|
21
|
+
if (this.system.render) {
|
|
22
|
+
this.system.render(frameState);
|
|
23
|
+
}
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
setActive(active) {
|
|
@@ -27,6 +28,6 @@ export class FacetedRendererAdapter extends RendererContract {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
dispose() {
|
|
30
|
-
this.system.
|
|
31
|
+
this.system.dispose();
|
|
31
32
|
}
|
|
32
33
|
}
|
|
@@ -7,16 +7,20 @@ export class HolographicRendererAdapter extends RendererContract {
|
|
|
7
7
|
this.system = system;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
init() {
|
|
11
|
-
return true;
|
|
10
|
+
init(context = {}) {
|
|
11
|
+
return this.system.init ? this.system.init(context) : true;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
resize() {
|
|
15
|
-
|
|
14
|
+
resize(width, height, pixelRatio = 1) {
|
|
15
|
+
if (this.system.resize) {
|
|
16
|
+
this.system.resize(width, height, pixelRatio);
|
|
17
|
+
}
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
render() {
|
|
19
|
-
this.system.
|
|
20
|
+
render(frameState) {
|
|
21
|
+
if (this.system.render) {
|
|
22
|
+
this.system.render(frameState);
|
|
23
|
+
}
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
setActive(active) {
|
|
@@ -24,6 +28,6 @@ export class HolographicRendererAdapter extends RendererContract {
|
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
dispose() {
|
|
27
|
-
this.system.
|
|
31
|
+
this.system.dispose();
|
|
28
32
|
}
|
|
29
33
|
}
|