@vib3code/sdk 2.0.1 → 2.0.3-canary.0a63e71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/DOCS/AGENT_HARNESS_ARCHITECTURE.md +245 -0
- package/DOCS/ANDROID_DEPLOYMENT.md +59 -0
- package/DOCS/ARCHITECTURE.md +1 -0
- package/DOCS/CI_TESTING.md +2 -0
- package/DOCS/CLI_ONBOARDING.md +3 -1
- package/DOCS/CONTROL_REFERENCE.md +2 -0
- package/DOCS/CROSS_SITE_DESIGN_PATTERNS.md +119 -0
- package/DOCS/ENV_SETUP.md +2 -0
- package/DOCS/EPIC_SCROLL_EVENTS.md +775 -0
- package/DOCS/EXPANSION_DESIGN.md +979 -0
- package/DOCS/EXPANSION_DESIGN_ULTRA.md +389 -0
- package/DOCS/EXPORT_FORMATS.md +2 -0
- package/DOCS/GPU_DISPOSAL_GUIDE.md +2 -0
- package/DOCS/HANDOFF_LANDING_PAGE.md +156 -0
- package/DOCS/HANDOFF_SDK_DEVELOPMENT.md +495 -0
- package/DOCS/LICENSING_TIERS.md +2 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +4 -2
- package/DOCS/MULTIVIZ_CHOREOGRAPHY_PATTERNS.md +939 -0
- package/DOCS/OBS_SETUP_GUIDE.md +2 -0
- package/DOCS/OPTIMIZATION_PLAN_MATH.md +119 -0
- package/DOCS/PRODUCT_STRATEGY.md +65 -0
- package/DOCS/PROJECT_SETUP.md +2 -0
- package/DOCS/README.md +105 -0
- package/DOCS/REFERENCE_SCROLL_ANALYSIS.md +99 -0
- package/DOCS/RENDERER_LIFECYCLE.md +2 -0
- package/DOCS/REPO_MANIFEST.md +2 -0
- package/DOCS/ROADMAP.md +113 -0
- package/DOCS/SCROLL_TIMELINE_v3.md +271 -0
- package/DOCS/SITE_REFACTOR_PLAN.md +102 -0
- package/DOCS/STATUS.md +26 -0
- package/DOCS/SYSTEM_INVENTORY.md +37 -32
- package/DOCS/TELEMETRY_EXPORTS.md +2 -0
- package/DOCS/VISUAL_ANALYSIS_CLICKERSS.md +87 -0
- package/DOCS/VISUAL_ANALYSIS_FACETAD.md +135 -0
- package/DOCS/VISUAL_ANALYSIS_SIMONE.md +97 -0
- package/DOCS/VISUAL_ANALYSIS_TABLESIDE.md +88 -0
- package/DOCS/WEBGPU_STATUS.md +121 -38
- package/DOCS/XR_BENCHMARKS.md +2 -0
- package/DOCS/archive/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +1 -0
- package/DOCS/archive/DEV_TRACK_ANALYSIS.md +1 -0
- package/DOCS/archive/DEV_TRACK_PLAN_2026-01-07.md +1 -0
- package/DOCS/archive/SESSION_014_PLAN.md +1 -0
- package/DOCS/archive/SESSION_LOG_2026-01-07.md +1 -0
- package/DOCS/archive/STRATEGIC_BLUEPRINT_2026-01-07.md +1 -0
- package/DOCS/archive/SYSTEM_AUDIT_2026-01-30.md +1 -0
- package/DOCS/archive/WEBGPU_STATUS_2026-02-15_STALE.md +1 -0
- package/DOCS/{DEV_TRACK_SESSION_2026-01-31.md → dev-tracks/DEV_TRACK_SESSION_2026-01-31.md} +3 -1
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-06.md +233 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-13.md +129 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-15.md +144 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +110 -0
- package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +310 -0
- package/DOCS/dev-tracks/README.md +12 -0
- package/README.md +26 -13
- package/cpp/CMakeLists.txt +236 -0
- package/cpp/bindings/embind.cpp +269 -0
- package/cpp/build.sh +129 -0
- package/cpp/geometry/Crystal.cpp +103 -0
- package/cpp/geometry/Fractal.cpp +136 -0
- package/cpp/geometry/GeometryGenerator.cpp +262 -0
- package/cpp/geometry/KleinBottle.cpp +71 -0
- package/cpp/geometry/Sphere.cpp +134 -0
- package/cpp/geometry/Tesseract.cpp +94 -0
- package/cpp/geometry/Tetrahedron.cpp +83 -0
- package/cpp/geometry/Torus.cpp +65 -0
- package/cpp/geometry/WarpFunctions.cpp +238 -0
- package/cpp/geometry/Wave.cpp +85 -0
- package/cpp/include/vib3_ffi.h +238 -0
- package/cpp/math/Mat4x4.cpp +409 -0
- package/cpp/math/Mat4x4.hpp +209 -0
- package/cpp/math/Projection.cpp +142 -0
- package/cpp/math/Projection.hpp +148 -0
- package/cpp/math/Rotor4D.cpp +322 -0
- package/cpp/math/Rotor4D.hpp +204 -0
- package/cpp/math/Vec4.cpp +303 -0
- package/cpp/math/Vec4.hpp +225 -0
- package/cpp/src/vib3_ffi.cpp +607 -0
- package/cpp/tests/Geometry_test.cpp +213 -0
- package/cpp/tests/Mat4x4_test.cpp +494 -0
- package/cpp/tests/Projection_test.cpp +298 -0
- package/cpp/tests/Rotor4D_test.cpp +423 -0
- package/cpp/tests/Vec4_test.cpp +489 -0
- package/docs/webgpu-live.html +1 -1
- package/package.json +41 -30
- package/src/agent/index.js +1 -3
- package/src/agent/mcp/MCPServer.js +1220 -144
- package/src/agent/mcp/index.js +1 -1
- package/src/agent/mcp/stdio-server.js +264 -0
- package/src/agent/mcp/tools.js +498 -31
- package/src/cli/index.js +431 -47
- package/src/core/CanvasManager.js +97 -204
- package/src/core/ErrorReporter.js +1 -1
- package/src/core/Parameters.js +1 -1
- package/src/core/VIB3Engine.js +93 -4
- package/src/core/VitalitySystem.js +53 -0
- package/src/core/index.js +18 -0
- package/src/core/renderers/FacetedRendererAdapter.js +10 -9
- package/src/core/renderers/HolographicRendererAdapter.js +13 -9
- package/src/core/renderers/QuantumRendererAdapter.js +11 -7
- package/src/creative/AestheticMapper.js +628 -0
- package/src/creative/ChoreographyPlayer.js +481 -0
- 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/TradingCardManager.js +3 -4
- package/src/export/index.js +11 -1
- package/src/faceted/FacetedSystem.js +260 -394
- package/src/games/glyph-war/GlyphWarVisualizer.js +641 -0
- package/src/geometry/generators/Crystal.js +2 -2
- package/src/geometry/warp/HypersphereCore.js +53 -24
- package/src/holograms/HolographicVisualizer.js +84 -98
- package/src/holograms/RealHolographicSystem.js +194 -43
- package/src/math/Mat4x4.js +308 -105
- package/src/math/Rotor4D.js +124 -40
- package/src/math/Vec4.js +200 -103
- package/src/math/index.js +7 -7
- package/src/polychora/PolychoraSystem.js +77 -0
- package/src/quantum/QuantumEngine.js +103 -66
- package/src/quantum/QuantumVisualizer.js +31 -22
- 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 +4 -1
- package/src/render/backends/WebGPUBackend.js +8 -4
- package/src/render/index.js +27 -2
- package/src/scene/Node4D.js +74 -24
- 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.glsl +220 -80
- package/src/shaders/faceted/faceted.frag.wgsl +144 -90
- package/src/shaders/holographic/holographic.frag.glsl +28 -9
- package/src/shaders/holographic/holographic.frag.wgsl +112 -41
- package/src/shaders/quantum/quantum.frag.glsl +1 -0
- package/src/shaders/quantum/quantum.frag.wgsl +6 -4
- 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/src/viewer/index.js +1 -1
- package/tools/headless-renderer.js +258 -0
- package/tools/shader-sync-verify.js +14 -8
- package/tools/site-analysis/all-reports.json +32 -0
- package/tools/site-analysis/combined-analysis.md +50 -0
- package/tools/site-analyzer.mjs +779 -0
- package/tools/visual-catalog/capture.js +276 -0
- package/tools/visual-catalog/composite.js +138 -0
- 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/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +0 -34
- package/DOCS/DEV_TRACK_ANALYSIS.md +0 -77
- package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +0 -42
- package/DOCS/SESSION_014_PLAN.md +0 -195
- package/DOCS/SESSION_LOG_2026-01-07.md +0 -56
- package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +0 -72
- package/DOCS/SYSTEM_AUDIT_2026-01-30.md +0 -738
- /package/src/viewer/{ReactivityManager.js → ViewerInputHandler.js} +0 -0
package/src/cli/index.js
CHANGED
|
@@ -5,9 +5,34 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { performance } from 'node:perf_hooks';
|
|
8
|
+
import path from 'node:path';
|
|
8
9
|
import { mcpServer, toolDefinitions } from '../agent/index.js';
|
|
9
10
|
import { schemaRegistry } from '../schemas/index.js';
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Resolves a file path and ensures it is within the current working directory.
|
|
14
|
+
* @param {string} filePath The path to validate
|
|
15
|
+
* @returns {string} The resolved absolute path
|
|
16
|
+
* @throws {Error} If the path is outside the allowed directory
|
|
17
|
+
*/
|
|
18
|
+
function getSafePath(filePath) {
|
|
19
|
+
if (!filePath) return filePath;
|
|
20
|
+
|
|
21
|
+
const cwd = process.cwd();
|
|
22
|
+
const resolvedPath = path.resolve(cwd, filePath);
|
|
23
|
+
const relative = path.relative(cwd, resolvedPath);
|
|
24
|
+
|
|
25
|
+
const isOutside = relative.startsWith('..') || path.isAbsolute(relative);
|
|
26
|
+
|
|
27
|
+
if (isOutside) {
|
|
28
|
+
const error = new Error('Security Error: Path traversal detected. Access denied.');
|
|
29
|
+
error.code = 'EACCES';
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return resolvedPath;
|
|
34
|
+
}
|
|
35
|
+
|
|
11
36
|
/**
|
|
12
37
|
* CLI Configuration
|
|
13
38
|
*/
|
|
@@ -172,7 +197,8 @@ function showHelp(isJson) {
|
|
|
172
197
|
description: 'VIB3+ 4D Visualization Engine CLI',
|
|
173
198
|
usage: `${CLI_NAME} <command> [options]`,
|
|
174
199
|
commands: {
|
|
175
|
-
|
|
200
|
+
init: 'Scaffold a new VIB3+ project (--template vanilla|react|vue|svelte)',
|
|
201
|
+
create: 'Create a new 4D visualization (--describe, --preset, --color, --hue, --XW, etc.)',
|
|
176
202
|
state: 'Get current engine state',
|
|
177
203
|
set: 'Set parameters (rotation, visual)',
|
|
178
204
|
geometry: 'Change or list geometries',
|
|
@@ -190,7 +216,14 @@ function showHelp(isJson) {
|
|
|
190
216
|
'--verbose': 'Verbose output'
|
|
191
217
|
},
|
|
192
218
|
examples: [
|
|
219
|
+
`${CLI_NAME} init my-app`,
|
|
220
|
+
`${CLI_NAME} init my-app --template react`,
|
|
221
|
+
`${CLI_NAME} init my-app --template vue`,
|
|
222
|
+
`${CLI_NAME} init my-app --template svelte`,
|
|
193
223
|
`${CLI_NAME} create --system quantum --geometry 8 --json`,
|
|
224
|
+
`${CLI_NAME} create --describe "serene ocean deep organic"`,
|
|
225
|
+
`${CLI_NAME} create --system holographic --preset energetic --color neon`,
|
|
226
|
+
`${CLI_NAME} create --system faceted --geometry 16 --XW 0.8 --YW 0.5 --hue 200`,
|
|
194
227
|
`${CLI_NAME} set rotation --XW 1.5 --YW 0.5`,
|
|
195
228
|
`${CLI_NAME} set visual --hue 200 --chaos 0.3`,
|
|
196
229
|
`${CLI_NAME} geometry list --core-type hypersphere`,
|
|
@@ -224,15 +257,84 @@ function showVersion(isJson) {
|
|
|
224
257
|
|
|
225
258
|
/**
|
|
226
259
|
* Handle 'create' command
|
|
260
|
+
*
|
|
261
|
+
* Supports full creative parameter control:
|
|
262
|
+
* vib3 create --system quantum --geometry 11 --hue 200 --chaos 0.3
|
|
263
|
+
* vib3 create --system holographic --preset energetic
|
|
264
|
+
* vib3 create --describe "serene ocean deep organic"
|
|
265
|
+
* vib3 create --system faceted --geometry 16 --XW 0.8 --YW 0.5 --speed 0.6
|
|
227
266
|
*/
|
|
228
267
|
async function handleCreate(parsed) {
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
268
|
+
const opts = parsed.options;
|
|
269
|
+
|
|
270
|
+
// Natural language description path — uses AestheticMapper
|
|
271
|
+
if (opts.describe || opts.description) {
|
|
272
|
+
const description = opts.describe || opts.description;
|
|
273
|
+
return await mcpServer.handleToolCall('design_from_description', {
|
|
274
|
+
description,
|
|
275
|
+
apply: true
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Step 1: Create the visualization scene
|
|
280
|
+
const createArgs = {
|
|
281
|
+
system: opts.system || 'quantum',
|
|
282
|
+
geometry_index: parseInt(opts.geometry || '0'),
|
|
283
|
+
projection: opts.projection || 'perspective'
|
|
233
284
|
};
|
|
285
|
+
const createResult = await mcpServer.handleToolCall('create_4d_visualization', createArgs);
|
|
286
|
+
|
|
287
|
+
// Step 2: Apply rotation if any 6D rotation flags provided
|
|
288
|
+
const rotationPlanes = ['XY', 'XZ', 'YZ', 'XW', 'YW', 'ZW'];
|
|
289
|
+
const rotationArgs = {};
|
|
290
|
+
let hasRotation = false;
|
|
291
|
+
for (const plane of rotationPlanes) {
|
|
292
|
+
if (opts[plane] !== undefined) {
|
|
293
|
+
rotationArgs[plane] = parseFloat(opts[plane]);
|
|
294
|
+
hasRotation = true;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
if (hasRotation) {
|
|
298
|
+
await mcpServer.handleToolCall('set_rotation', rotationArgs);
|
|
299
|
+
}
|
|
234
300
|
|
|
235
|
-
|
|
301
|
+
// Step 3: Apply visual parameters if any provided
|
|
302
|
+
const visualKeys = ['hue', 'saturation', 'intensity', 'speed', 'chaos', 'morphFactor', 'gridDensity', 'dimension'];
|
|
303
|
+
const visualArgs = {};
|
|
304
|
+
let hasVisual = false;
|
|
305
|
+
for (const key of visualKeys) {
|
|
306
|
+
if (opts[key] !== undefined) {
|
|
307
|
+
visualArgs[key] = key === 'hue' ? parseInt(opts[key]) : parseFloat(opts[key]);
|
|
308
|
+
hasVisual = true;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (hasVisual) {
|
|
312
|
+
await mcpServer.handleToolCall('set_visual_parameters', visualArgs);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Step 4: Apply behavior preset if specified (ambient, reactive, immersive, energetic, calm, cinematic)
|
|
316
|
+
if (opts.preset) {
|
|
317
|
+
const presetDefaults = {
|
|
318
|
+
ambient: { speed: 0.3, chaos: 0.1 },
|
|
319
|
+
reactive: { speed: 1.0, chaos: 0.3 },
|
|
320
|
+
immersive: { speed: 0.8, chaos: 0.15 },
|
|
321
|
+
energetic: { speed: 2.5, chaos: 0.8 },
|
|
322
|
+
calm: { speed: 0.2, chaos: 0.05 },
|
|
323
|
+
cinematic: { speed: 0.5, chaos: 0.2 }
|
|
324
|
+
};
|
|
325
|
+
const presetParams = presetDefaults[opts.preset];
|
|
326
|
+
if (presetParams) {
|
|
327
|
+
await mcpServer.handleToolCall('set_visual_parameters', presetParams);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Step 5: Apply color preset if specified (ocean, neon, galaxy, etc.)
|
|
332
|
+
if (opts.color || opts.colorPreset) {
|
|
333
|
+
const colorName = opts.color || opts.colorPreset;
|
|
334
|
+
await mcpServer.handleToolCall('apply_color_preset', { preset: colorName });
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return createResult;
|
|
236
338
|
}
|
|
237
339
|
|
|
238
340
|
/**
|
|
@@ -369,7 +471,7 @@ async function handleTools(parsed, startTime) {
|
|
|
369
471
|
*/
|
|
370
472
|
async function handleValidate(parsed, startTime) {
|
|
371
473
|
const subcommand = parsed.subcommand || 'pack';
|
|
372
|
-
|
|
474
|
+
let filePath = parsed.options.file || parsed.options.f || parsed.positional[0];
|
|
373
475
|
|
|
374
476
|
if (!filePath && subcommand !== 'schema') {
|
|
375
477
|
return wrapResponse('validate', {
|
|
@@ -383,6 +485,10 @@ async function handleValidate(parsed, startTime) {
|
|
|
383
485
|
}
|
|
384
486
|
|
|
385
487
|
try {
|
|
488
|
+
if (filePath) {
|
|
489
|
+
filePath = getSafePath(filePath);
|
|
490
|
+
}
|
|
491
|
+
|
|
386
492
|
switch (subcommand) {
|
|
387
493
|
case 'pack': {
|
|
388
494
|
// Validate a .vib3 scene pack file
|
|
@@ -456,6 +562,17 @@ async function handleValidate(parsed, startTime) {
|
|
|
456
562
|
}, false, performance.now() - startTime);
|
|
457
563
|
}
|
|
458
564
|
} catch (error) {
|
|
565
|
+
if (error.code === 'EACCES') {
|
|
566
|
+
return wrapResponse('validate', {
|
|
567
|
+
error: {
|
|
568
|
+
type: 'SecurityError',
|
|
569
|
+
code: 'ACCESS_DENIED',
|
|
570
|
+
message: error.message,
|
|
571
|
+
suggestion: 'Ensure the file path is within the project directory'
|
|
572
|
+
}
|
|
573
|
+
}, false, performance.now() - startTime);
|
|
574
|
+
}
|
|
575
|
+
|
|
459
576
|
if (error.code === 'ENOENT') {
|
|
460
577
|
return wrapResponse('validate', {
|
|
461
578
|
error: {
|
|
@@ -578,13 +695,43 @@ async function main() {
|
|
|
578
695
|
|
|
579
696
|
/**
|
|
580
697
|
* Handle init command — scaffold a new VIB3+ project
|
|
698
|
+
* Supports --template vanilla|react|vue|svelte
|
|
581
699
|
*/
|
|
582
700
|
async function handleInit(parsed, startTime) {
|
|
583
701
|
const { writeFileSync, mkdirSync, existsSync } = await import('node:fs');
|
|
584
|
-
const { join } = await import('node:path');
|
|
585
702
|
|
|
586
|
-
const projectName = parsed.positional[0] || 'my-vib3-app';
|
|
587
|
-
const
|
|
703
|
+
const projectName = parsed.subcommand || parsed.positional[0] || 'my-vib3-app';
|
|
704
|
+
const template = parsed.options.template || parsed.options.t || 'vanilla';
|
|
705
|
+
const validTemplates = ['vanilla', 'react', 'vue', 'svelte'];
|
|
706
|
+
|
|
707
|
+
if (!validTemplates.includes(template)) {
|
|
708
|
+
return wrapResponse('init', {
|
|
709
|
+
error: {
|
|
710
|
+
type: 'ValidationError',
|
|
711
|
+
code: 'INVALID_TEMPLATE',
|
|
712
|
+
message: `Unknown template: ${template}`,
|
|
713
|
+
valid_options: validTemplates,
|
|
714
|
+
suggestion: `Use --template ${validTemplates.join('|')}`
|
|
715
|
+
}
|
|
716
|
+
}, false, performance.now() - startTime);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
let projectDir;
|
|
720
|
+
try {
|
|
721
|
+
projectDir = getSafePath(projectName);
|
|
722
|
+
} catch (error) {
|
|
723
|
+
if (error.code === 'EACCES') {
|
|
724
|
+
return wrapResponse('init', {
|
|
725
|
+
error: {
|
|
726
|
+
type: 'SecurityError',
|
|
727
|
+
code: 'ACCESS_DENIED',
|
|
728
|
+
message: error.message,
|
|
729
|
+
suggestion: 'Choose a project name that results in a valid subdirectory'
|
|
730
|
+
}
|
|
731
|
+
}, false, performance.now() - startTime);
|
|
732
|
+
}
|
|
733
|
+
throw error;
|
|
734
|
+
}
|
|
588
735
|
|
|
589
736
|
if (existsSync(projectDir)) {
|
|
590
737
|
return wrapResponse('init', {
|
|
@@ -599,25 +746,277 @@ async function handleInit(parsed, startTime) {
|
|
|
599
746
|
|
|
600
747
|
mkdirSync(projectDir, { recursive: true });
|
|
601
748
|
|
|
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'
|
|
749
|
+
const files = getTemplateFiles(template, projectName);
|
|
750
|
+
|
|
751
|
+
for (const [filename, content] of Object.entries(files)) {
|
|
752
|
+
const filepath = path.join(projectDir, filename);
|
|
753
|
+
const dir = path.join(projectDir, filename.split('/').slice(0, -1).join('/'));
|
|
754
|
+
if (dir !== projectDir) {
|
|
755
|
+
mkdirSync(dir, { recursive: true });
|
|
616
756
|
}
|
|
617
|
-
|
|
757
|
+
writeFileSync(filepath, content);
|
|
758
|
+
}
|
|
618
759
|
|
|
619
|
-
|
|
620
|
-
|
|
760
|
+
const fileNames = Object.keys(files);
|
|
761
|
+
const tree = fileNames.map((f, i) =>
|
|
762
|
+
` ${i === fileNames.length - 1 ? '└── ' : '├── '}${f}`
|
|
763
|
+
).join('\n');
|
|
764
|
+
|
|
765
|
+
console.log(`\n Created ${projectName}/ (${template} template)`);
|
|
766
|
+
console.log(tree);
|
|
767
|
+
console.log(`\n Next steps:`);
|
|
768
|
+
console.log(` cd ${projectName}`);
|
|
769
|
+
console.log(' npm install');
|
|
770
|
+
console.log(' npm run dev\n');
|
|
771
|
+
|
|
772
|
+
return wrapResponse('init', {
|
|
773
|
+
project: projectName,
|
|
774
|
+
template,
|
|
775
|
+
files: fileNames,
|
|
776
|
+
next_steps: [`cd ${projectName}`, 'npm install', 'npm run dev']
|
|
777
|
+
}, true, performance.now() - startTime);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Generate template files based on framework choice
|
|
782
|
+
*/
|
|
783
|
+
function getTemplateFiles(template, projectName) {
|
|
784
|
+
const sdkDep = { '@vib3code/sdk': '^2.0.0' };
|
|
785
|
+
const viteDep = { vite: '^5.3.0' };
|
|
786
|
+
|
|
787
|
+
switch (template) {
|
|
788
|
+
case 'react':
|
|
789
|
+
return {
|
|
790
|
+
'package.json': JSON.stringify({
|
|
791
|
+
name: projectName,
|
|
792
|
+
version: '0.1.0',
|
|
793
|
+
type: 'module',
|
|
794
|
+
scripts: { dev: 'npx vite --open', build: 'npx vite build' },
|
|
795
|
+
dependencies: { ...sdkDep, react: '^18.3.0', 'react-dom': '^18.3.0' },
|
|
796
|
+
devDependencies: { ...viteDep, '@vitejs/plugin-react': '^4.3.0' }
|
|
797
|
+
}, null, 2) + '\n',
|
|
798
|
+
'vite.config.js': `import { defineConfig } from 'vite';
|
|
799
|
+
import react from '@vitejs/plugin-react';
|
|
800
|
+
export default defineConfig({ plugins: [react()] });
|
|
801
|
+
`,
|
|
802
|
+
'index.html': `<!DOCTYPE html>
|
|
803
|
+
<html lang="en">
|
|
804
|
+
<head>
|
|
805
|
+
<meta charset="utf-8">
|
|
806
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
807
|
+
<title>${projectName}</title>
|
|
808
|
+
</head>
|
|
809
|
+
<body>
|
|
810
|
+
<div id="root"></div>
|
|
811
|
+
<script type="module" src="/src/main.jsx"></script>
|
|
812
|
+
</body>
|
|
813
|
+
</html>
|
|
814
|
+
`,
|
|
815
|
+
'src/main.jsx': `import React from 'react';
|
|
816
|
+
import ReactDOM from 'react-dom/client';
|
|
817
|
+
import App from './App.jsx';
|
|
818
|
+
|
|
819
|
+
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
|
|
820
|
+
`,
|
|
821
|
+
'src/App.jsx': `import React, { useRef, useEffect, useState } from 'react';
|
|
822
|
+
import { VIB3Engine } from '@vib3code/sdk/core';
|
|
823
|
+
|
|
824
|
+
export default function App() {
|
|
825
|
+
const engineRef = useRef(null);
|
|
826
|
+
const [system, setSystem] = useState('quantum');
|
|
827
|
+
const [geometry, setGeometry] = useState(0);
|
|
828
|
+
const [hue, setHue] = useState(200);
|
|
829
|
+
|
|
830
|
+
useEffect(() => {
|
|
831
|
+
const engine = new VIB3Engine();
|
|
832
|
+
engineRef.current = engine;
|
|
833
|
+
engine.initialize().then(() => engine.switchSystem(system));
|
|
834
|
+
return () => engine.destroy();
|
|
835
|
+
}, []);
|
|
836
|
+
|
|
837
|
+
useEffect(() => {
|
|
838
|
+
engineRef.current?.switchSystem(system);
|
|
839
|
+
}, [system]);
|
|
840
|
+
|
|
841
|
+
useEffect(() => {
|
|
842
|
+
engineRef.current?.setParameter('geometry', geometry);
|
|
843
|
+
}, [geometry]);
|
|
844
|
+
|
|
845
|
+
useEffect(() => {
|
|
846
|
+
engineRef.current?.setParameter('hue', hue);
|
|
847
|
+
}, [hue]);
|
|
848
|
+
|
|
849
|
+
return (
|
|
850
|
+
<div style={{ margin: 0, background: '#07070f', minHeight: '100vh' }}>
|
|
851
|
+
<div style={{ position: 'fixed', top: 12, left: 12, zIndex: 10, font: '13px monospace', color: '#0fc', display: 'flex', gap: 12 }}>
|
|
852
|
+
<label>System:
|
|
853
|
+
<select value={system} onChange={e => setSystem(e.target.value)} style={{ marginLeft: 6 }}>
|
|
854
|
+
<option>quantum</option>
|
|
855
|
+
<option>faceted</option>
|
|
856
|
+
<option>holographic</option>
|
|
857
|
+
</select>
|
|
858
|
+
</label>
|
|
859
|
+
<label>Geometry: <input type="range" min="0" max="23" value={geometry} onChange={e => setGeometry(+e.target.value)} /></label>
|
|
860
|
+
<label>Hue: <input type="range" min="0" max="360" value={hue} onChange={e => setHue(+e.target.value)} /></label>
|
|
861
|
+
</div>
|
|
862
|
+
</div>
|
|
863
|
+
);
|
|
864
|
+
}
|
|
865
|
+
`
|
|
866
|
+
};
|
|
867
|
+
|
|
868
|
+
case 'vue':
|
|
869
|
+
return {
|
|
870
|
+
'package.json': JSON.stringify({
|
|
871
|
+
name: projectName,
|
|
872
|
+
version: '0.1.0',
|
|
873
|
+
type: 'module',
|
|
874
|
+
scripts: { dev: 'npx vite --open', build: 'npx vite build' },
|
|
875
|
+
dependencies: { ...sdkDep, vue: '^3.4.0' },
|
|
876
|
+
devDependencies: { ...viteDep, '@vitejs/plugin-vue': '^5.1.0' }
|
|
877
|
+
}, null, 2) + '\n',
|
|
878
|
+
'vite.config.js': `import { defineConfig } from 'vite';
|
|
879
|
+
import vue from '@vitejs/plugin-vue';
|
|
880
|
+
export default defineConfig({ plugins: [vue()] });
|
|
881
|
+
`,
|
|
882
|
+
'index.html': `<!DOCTYPE html>
|
|
883
|
+
<html lang="en">
|
|
884
|
+
<head>
|
|
885
|
+
<meta charset="utf-8">
|
|
886
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
887
|
+
<title>${projectName}</title>
|
|
888
|
+
</head>
|
|
889
|
+
<body>
|
|
890
|
+
<div id="app"></div>
|
|
891
|
+
<script type="module" src="/src/main.js"></script>
|
|
892
|
+
</body>
|
|
893
|
+
</html>
|
|
894
|
+
`,
|
|
895
|
+
'src/main.js': `import { createApp } from 'vue';
|
|
896
|
+
import App from './App.vue';
|
|
897
|
+
createApp(App).mount('#app');
|
|
898
|
+
`,
|
|
899
|
+
'src/App.vue': `<script setup>
|
|
900
|
+
import { ref, onMounted, onUnmounted, watch } from 'vue';
|
|
901
|
+
import { VIB3Engine } from '@vib3code/sdk/core';
|
|
902
|
+
|
|
903
|
+
const engine = ref(null);
|
|
904
|
+
const system = ref('quantum');
|
|
905
|
+
const geometry = ref(0);
|
|
906
|
+
const hue = ref(200);
|
|
907
|
+
|
|
908
|
+
onMounted(async () => {
|
|
909
|
+
engine.value = new VIB3Engine();
|
|
910
|
+
await engine.value.initialize();
|
|
911
|
+
await engine.value.switchSystem(system.value);
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
onUnmounted(() => engine.value?.destroy());
|
|
915
|
+
|
|
916
|
+
watch(system, (val) => engine.value?.switchSystem(val));
|
|
917
|
+
watch(geometry, (val) => engine.value?.setParameter('geometry', val));
|
|
918
|
+
watch(hue, (val) => engine.value?.setParameter('hue', val));
|
|
919
|
+
</script>
|
|
920
|
+
|
|
921
|
+
<template>
|
|
922
|
+
<div style="margin: 0; background: #07070f; min-height: 100vh">
|
|
923
|
+
<div style="position: fixed; top: 12px; left: 12px; z-index: 10; font: 13px monospace; color: #0fc; display: flex; gap: 12px">
|
|
924
|
+
<label>System:
|
|
925
|
+
<select v-model="system" style="margin-left: 6px">
|
|
926
|
+
<option>quantum</option>
|
|
927
|
+
<option>faceted</option>
|
|
928
|
+
<option>holographic</option>
|
|
929
|
+
</select>
|
|
930
|
+
</label>
|
|
931
|
+
<label>Geometry: <input type="range" min="0" max="23" v-model.number="geometry" /></label>
|
|
932
|
+
<label>Hue: <input type="range" min="0" max="360" v-model.number="hue" /></label>
|
|
933
|
+
</div>
|
|
934
|
+
</div>
|
|
935
|
+
</template>
|
|
936
|
+
`
|
|
937
|
+
};
|
|
938
|
+
|
|
939
|
+
case 'svelte':
|
|
940
|
+
return {
|
|
941
|
+
'package.json': JSON.stringify({
|
|
942
|
+
name: projectName,
|
|
943
|
+
version: '0.1.0',
|
|
944
|
+
type: 'module',
|
|
945
|
+
scripts: { dev: 'npx vite --open', build: 'npx vite build' },
|
|
946
|
+
dependencies: sdkDep,
|
|
947
|
+
devDependencies: { ...viteDep, '@sveltejs/vite-plugin-svelte': '^3.2.0', svelte: '^4.2.0' }
|
|
948
|
+
}, null, 2) + '\n',
|
|
949
|
+
'vite.config.js': `import { defineConfig } from 'vite';
|
|
950
|
+
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
951
|
+
export default defineConfig({ plugins: [svelte()] });
|
|
952
|
+
`,
|
|
953
|
+
'index.html': `<!DOCTYPE html>
|
|
954
|
+
<html lang="en">
|
|
955
|
+
<head>
|
|
956
|
+
<meta charset="utf-8">
|
|
957
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
958
|
+
<title>${projectName}</title>
|
|
959
|
+
</head>
|
|
960
|
+
<body>
|
|
961
|
+
<div id="app"></div>
|
|
962
|
+
<script type="module" src="/src/main.js"></script>
|
|
963
|
+
</body>
|
|
964
|
+
</html>
|
|
965
|
+
`,
|
|
966
|
+
'src/main.js': `import App from './App.svelte';
|
|
967
|
+
const app = new App({ target: document.getElementById('app') });
|
|
968
|
+
export default app;
|
|
969
|
+
`,
|
|
970
|
+
'src/App.svelte': `<script>
|
|
971
|
+
import { onMount, onDestroy } from 'svelte';
|
|
972
|
+
import { VIB3Engine } from '@vib3code/sdk/core';
|
|
973
|
+
|
|
974
|
+
let engine = null;
|
|
975
|
+
let system = 'quantum';
|
|
976
|
+
let geometry = 0;
|
|
977
|
+
let hue = 200;
|
|
978
|
+
|
|
979
|
+
onMount(async () => {
|
|
980
|
+
engine = new VIB3Engine();
|
|
981
|
+
await engine.initialize();
|
|
982
|
+
await engine.switchSystem(system);
|
|
983
|
+
});
|
|
984
|
+
|
|
985
|
+
onDestroy(() => engine?.destroy());
|
|
986
|
+
|
|
987
|
+
$: engine?.switchSystem(system);
|
|
988
|
+
$: engine?.setParameter('geometry', geometry);
|
|
989
|
+
$: engine?.setParameter('hue', hue);
|
|
990
|
+
</script>
|
|
991
|
+
|
|
992
|
+
<div style="margin: 0; background: #07070f; min-height: 100vh">
|
|
993
|
+
<div style="position: fixed; top: 12px; left: 12px; z-index: 10; font: 13px monospace; color: #0fc; display: flex; gap: 12px">
|
|
994
|
+
<label>System:
|
|
995
|
+
<select bind:value={system} style="margin-left: 6px">
|
|
996
|
+
<option>quantum</option>
|
|
997
|
+
<option>faceted</option>
|
|
998
|
+
<option>holographic</option>
|
|
999
|
+
</select>
|
|
1000
|
+
</label>
|
|
1001
|
+
<label>Geometry: <input type="range" min="0" max="23" bind:value={geometry} /></label>
|
|
1002
|
+
<label>Hue: <input type="range" min="0" max="360" bind:value={hue} /></label>
|
|
1003
|
+
</div>
|
|
1004
|
+
</div>
|
|
1005
|
+
`
|
|
1006
|
+
};
|
|
1007
|
+
|
|
1008
|
+
case 'vanilla':
|
|
1009
|
+
default:
|
|
1010
|
+
return {
|
|
1011
|
+
'package.json': JSON.stringify({
|
|
1012
|
+
name: projectName,
|
|
1013
|
+
version: '0.1.0',
|
|
1014
|
+
type: 'module',
|
|
1015
|
+
scripts: { dev: 'npx vite --open', build: 'npx vite build' },
|
|
1016
|
+
dependencies: sdkDep,
|
|
1017
|
+
devDependencies: viteDep
|
|
1018
|
+
}, null, 2) + '\n',
|
|
1019
|
+
'index.html': `<!DOCTYPE html>
|
|
621
1020
|
<html lang="en">
|
|
622
1021
|
<head>
|
|
623
1022
|
<meta charset="utf-8">
|
|
@@ -638,10 +1037,8 @@ async function handleInit(parsed, startTime) {
|
|
|
638
1037
|
<script type="module" src="main.js"></script>
|
|
639
1038
|
</body>
|
|
640
1039
|
</html>
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
// main.js
|
|
644
|
-
writeFileSync(join(projectDir, 'main.js'), `import { VIB3Engine } from '@vib3code/sdk/core';
|
|
1040
|
+
`,
|
|
1041
|
+
'main.js': `import { VIB3Engine } from '@vib3code/sdk/core';
|
|
645
1042
|
|
|
646
1043
|
const engine = new VIB3Engine();
|
|
647
1044
|
await engine.initialize();
|
|
@@ -650,22 +1047,9 @@ await engine.switchSystem('quantum');
|
|
|
650
1047
|
document.getElementById('sys').addEventListener('change', (e) => engine.switchSystem(e.target.value));
|
|
651
1048
|
document.getElementById('geo').addEventListener('input', (e) => engine.setParameter('geometry', +e.target.value));
|
|
652
1049
|
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);
|
|
1050
|
+
`
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
669
1053
|
}
|
|
670
1054
|
|
|
671
1055
|
// Run CLI
|