@volter/editor-threejs 0.5.68 → 0.5.69

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 (43) hide show
  1. package/NOTICE +3 -3
  2. package/contributions/animation-mixers.service.ts +1 -1
  3. package/contributions/animation-timeline.utility.tsx +1 -1
  4. package/dist-node/serving.mjs +10 -10
  5. package/package.json +4 -4
  6. package/serving/animation-live-module.ts +6 -6
  7. package/serving/animation-stamp.ts +5 -5
  8. package/serving/index.ts +1 -1
  9. package/src/adapter/hierarchy-marks.ts +5 -5
  10. package/src/adapter/ingest/scene-capture.ts +7 -7
  11. package/src/adapter/ingest/structural-ids.ts +1 -1
  12. package/src/adapter/ingest/visible-capture-window.ts +3 -3
  13. package/src/asset-loaders.ts +1 -1
  14. package/src/ecs/object-marks.ts +4 -4
  15. package/src/ecs/user-data.ts +3 -3
  16. package/src/kit/asset-compare.ts +2 -2
  17. package/src/kit/asset-preview-command.ts +2 -2
  18. package/src/kit/asset-preview.ts +1 -1
  19. package/src/kit/authoring/component-instance-root.ts +2 -2
  20. package/src/kit/authoring/object3d-document-session.ts +1 -1
  21. package/src/kit/authoring/three-projection-core.ts +1 -1
  22. package/src/kit/authoring/viewport-pick-context.ts +1 -1
  23. package/src/kit/authoring/viewport-raycast.ts +1 -1
  24. package/src/kit/components/CameraInfo.tsx +1 -1
  25. package/src/kit/components/InspectorObjectPreview.tsx +1 -1
  26. package/src/kit/components/Object3DDocumentToolbar.tsx +10 -10
  27. package/src/kit/components/StageHost.tsx +14 -14
  28. package/src/kit/components/StatsOverlay.tsx +4 -4
  29. package/src/kit/components/ViewportFurniture.tsx +22 -22
  30. package/src/kit/components/ViewportOverlay.tsx +4 -4
  31. package/src/kit/components/ViewportShadingMenu.tsx +9 -9
  32. package/src/kit/components/ViewportViewMenu.tsx +1 -1
  33. package/src/kit/components/stage-presence-markers.ts +2 -2
  34. package/src/kit/components/standard-viewport-dressing.ts +18 -18
  35. package/src/kit/editor-shell-store.ts +1 -1
  36. package/src/kit/editor-viewport.ts +17 -17
  37. package/src/kit/live-module-source.ts +1 -1
  38. package/src/kit/projection/three.ts +3 -3
  39. package/src/kit/three-viewport/selection-outline.ts +9 -9
  40. package/src/kit/three-viewport/skeleton-helper.ts +1 -1
  41. package/src/kit/three-viewport/studio-environment.ts +1 -1
  42. package/src/kit/viewport-hotkeys.ts +2 -2
  43. package/src/viewport/content-bounds.ts +1 -1
package/NOTICE CHANGED
@@ -1,13 +1,13 @@
1
1
  Copyright 2026 Volter AI, Inc.
2
2
 
3
3
  Modules under src/viewport and src/capture were imported from the
4
- AGPL-3.0-only @vgai/threejs package; LICENSE contains that license.
4
+ AGPL-3.0-only threejs package of volter-ai/volter-engine; LICENSE contains that license.
5
5
  serving/model-import-conversion.ts was imported from the AGPL-3.0-only
6
- @vgai/editor package's server and retains that license.
6
+ editor package's server in volter-ai/volter-engine and retains that license.
7
7
 
8
8
  Modules under src/adapter, src/animation, src/ecs and src/render, together
9
9
  with src/asset-loaders.ts, src/asset-parse-error.ts and src/loader.ts, were
10
- imported from the Apache-2.0 @vgai/threejs-runtime package. They retain that
10
+ imported from the Apache-2.0 @volter/threejs-runtime package. They retain that
11
11
  license; LICENSE-APACHE contains its text.
12
12
 
13
13
  Source revisions and original file hashes are recorded in the repository's
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The animation stamp's status facet (`@volter/editor-sdk/services`, a `workspace.service`
3
- * contribution): `vgai status` reports the mixers the running world's own code made, with the
3
+ * contribution): the editor's `status` command reports the mixers the running world's own code made, with the
4
4
  * clips it has played through each and the objects each animates, so "the timeline found
5
5
  * nothing" is answerable from the session.
6
6
  */
@@ -32,7 +32,7 @@ export default function AnimationTimeline() {
32
32
  data-testid="animation-timeline-empty"
33
33
  data-document={activeId ?? ''}
34
34
  data-transport={handle ? 'yes' : 'no'}
35
- style={{ padding: 'var(--vgai-space-2) var(--vgai-space-3)' }}
35
+ style={{ padding: 'var(--volter-space-2) var(--volter-space-3)' }}
36
36
  >
37
37
  {handle
38
38
  ? 'Nothing in the active document plays an animation.'
@@ -3,7 +3,7 @@ import { relative, sep } from "node:path";
3
3
  import ts from "typescript";
4
4
 
5
5
  // serving/animation-live-module.ts
6
- var ANIMATION_LIVE_MODULE_ID = "virtual:vgai-three-animation-live";
6
+ var ANIMATION_LIVE_MODULE_ID = "virtual:volter-three-animation-live";
7
7
  var animationLiveModuleSource = `
8
8
  const live = (globalThis[Symbol.for('volter.three.animation.live')] ??= {
9
9
  mixers: new Map(),
@@ -16,10 +16,10 @@ function notify() {
16
16
  try { listener(); } catch (error) { console.error(error); }
17
17
  }
18
18
  }
19
- export function __vgaiMixer(mixer, key) {
19
+ export function __volterMixer(mixer, key) {
20
20
  if (!mixer || typeof mixer.clipAction !== 'function') return mixer;
21
- if (mixer.__vgaiMixerKey) return mixer;
22
- Object.defineProperty(mixer, '__vgaiMixerKey', { value: key });
21
+ if (mixer.__volterMixerKey) return mixer;
22
+ Object.defineProperty(mixer, '__volterMixerKey', { value: key });
23
23
  const entry = { key, mixer, clips: new Map(), roots: new Set() };
24
24
  live.mixers.set(mixer, entry);
25
25
  const clipAction = mixer.clipAction;
@@ -47,9 +47,9 @@ export function __vgaiMixer(mixer, key) {
47
47
  return mixer;
48
48
  }
49
49
  /** drei's \`useAnimations\` result: its mixer, and the clips it was handed. */
50
- export function __vgaiAnimations(result, key) {
50
+ export function __volterAnimations(result, key) {
51
51
  if (!result || !result.mixer) return result;
52
- __vgaiMixer(result.mixer, key);
52
+ __volterMixer(result.mixer, key);
53
53
  const entry = live.mixers.get(result.mixer);
54
54
  if (entry && Array.isArray(result.clips)) {
55
55
  let changed = false;
@@ -81,8 +81,8 @@ function stampAnimation(code, file, relativeFile) {
81
81
  const source = ts.createSourceFile(file, code, ts.ScriptTarget.Latest, true, kind);
82
82
  const sites = [];
83
83
  const visit = (node) => {
84
- if (isMixerConstruction(node)) sites.push({ start: node.getStart(source), end: node.getEnd(), wrapper: "__vgaiMixer" });
85
- else if (isUseAnimations(node)) sites.push({ start: node.getStart(source), end: node.getEnd(), wrapper: "__vgaiAnimations" });
84
+ if (isMixerConstruction(node)) sites.push({ start: node.getStart(source), end: node.getEnd(), wrapper: "__volterMixer" });
85
+ else if (isUseAnimations(node)) sites.push({ start: node.getStart(source), end: node.getEnd(), wrapper: "__volterAnimations" });
86
86
  ts.forEachChild(node, visit);
87
87
  };
88
88
  visit(source);
@@ -93,7 +93,7 @@ function stampAnimation(code, file, relativeFile) {
93
93
  const key = `${relativeFile}:${line + 1}:${character + 1}`;
94
94
  out = `${out.slice(0, site.start)}${site.wrapper}(${out.slice(site.start, site.end)}, ${JSON.stringify(key)})${out.slice(site.end)}`;
95
95
  }
96
- return `import { __vgaiMixer, __vgaiAnimations } from ${JSON.stringify(ANIMATION_LIVE_MODULE_ID)};
96
+ return `import { __volterMixer, __volterAnimations } from ${JSON.stringify(ANIMATION_LIVE_MODULE_ID)};
97
97
  ${out}`;
98
98
  }
99
99
  function animationStampPlugin(services) {
@@ -104,7 +104,7 @@ function animationStampPlugin(services) {
104
104
  return roots.some((root) => file.startsWith(root + sep) || file.startsWith(root + "/"));
105
105
  };
106
106
  return {
107
- name: "vgai-three-animation",
107
+ name: "volter-three-animation",
108
108
  enforce: "pre",
109
109
  resolveId(id) {
110
110
  return id === ANIMATION_LIVE_MODULE_ID ? VIRTUAL_ID : null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@volter/editor-threejs",
3
3
  "author": "Volter AI, Inc.",
4
- "version": "0.5.68",
4
+ "version": "0.5.69",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -126,7 +126,7 @@
126
126
  "prepack": "npm run build",
127
127
  "typecheck": "tsc -p tsconfig.json"
128
128
  },
129
- "vgai": {
129
+ "volter": {
130
130
  "contributions": [
131
131
  "./contributions/three-integration.service.ts",
132
132
  "./contributions/animation-mixers.service.ts",
@@ -135,12 +135,12 @@
135
135
  "serving": "./dist-node/serving.mjs"
136
136
  },
137
137
  "dependencies": {
138
- "@volter/editor-project": "0.5.68",
138
+ "@volter/editor-project": "0.5.69",
139
139
  "@sparkjsdev/spark": "^2.1.0",
140
140
  "three.quarks": "^0.16.0",
141
141
  "zod": "^4.3.6",
142
142
  "typescript": "5.9.3",
143
- "@volter/editor-sdk": "0.5.68",
143
+ "@volter/editor-sdk": "0.5.69",
144
144
  "postprocessing": "6.38.3",
145
145
  "quarks.core": "0.16.0",
146
146
  "@fortawesome/free-solid-svg-icons": "^7.2.0"
@@ -9,7 +9,7 @@
9
9
  * the editor's bundle reads it (`src/animation/live-mixers.ts`).
10
10
  */
11
11
 
12
- export const ANIMATION_LIVE_MODULE_ID = 'virtual:vgai-three-animation-live';
12
+ export const ANIMATION_LIVE_MODULE_ID = 'virtual:volter-three-animation-live';
13
13
 
14
14
  export const animationLiveModuleSource = `
15
15
  const live = (globalThis[Symbol.for('volter.three.animation.live')] ??= {
@@ -23,10 +23,10 @@ function notify() {
23
23
  try { listener(); } catch (error) { console.error(error); }
24
24
  }
25
25
  }
26
- export function __vgaiMixer(mixer, key) {
26
+ export function __volterMixer(mixer, key) {
27
27
  if (!mixer || typeof mixer.clipAction !== 'function') return mixer;
28
- if (mixer.__vgaiMixerKey) return mixer;
29
- Object.defineProperty(mixer, '__vgaiMixerKey', { value: key });
28
+ if (mixer.__volterMixerKey) return mixer;
29
+ Object.defineProperty(mixer, '__volterMixerKey', { value: key });
30
30
  const entry = { key, mixer, clips: new Map(), roots: new Set() };
31
31
  live.mixers.set(mixer, entry);
32
32
  const clipAction = mixer.clipAction;
@@ -54,9 +54,9 @@ export function __vgaiMixer(mixer, key) {
54
54
  return mixer;
55
55
  }
56
56
  /** drei's \`useAnimations\` result: its mixer, and the clips it was handed. */
57
- export function __vgaiAnimations(result, key) {
57
+ export function __volterAnimations(result, key) {
58
58
  if (!result || !result.mixer) return result;
59
- __vgaiMixer(result.mixer, key);
59
+ __volterMixer(result.mixer, key);
60
60
  const entry = live.mixers.get(result.mixer);
61
61
  if (entry && Array.isArray(result.clips)) {
62
62
  let changed = false;
@@ -40,10 +40,10 @@ export function stampAnimation(code: string, file: string, relativeFile: string)
40
40
  if (!code.includes('AnimationMixer') && !code.includes('useAnimations')) return null;
41
41
  const kind = file.endsWith('.tsx') ? ts.ScriptKind.TSX : file.endsWith('.jsx') ? ts.ScriptKind.JSX : ts.ScriptKind.TS;
42
42
  const source = ts.createSourceFile(file, code, ts.ScriptTarget.Latest, true, kind);
43
- const sites: { start: number; end: number; wrapper: '__vgaiMixer' | '__vgaiAnimations' }[] = [];
43
+ const sites: { start: number; end: number; wrapper: '__volterMixer' | '__volterAnimations' }[] = [];
44
44
  const visit = (node: ts.Node): void => {
45
- if (isMixerConstruction(node)) sites.push({ start: node.getStart(source), end: node.getEnd(), wrapper: '__vgaiMixer' });
46
- else if (isUseAnimations(node)) sites.push({ start: node.getStart(source), end: node.getEnd(), wrapper: '__vgaiAnimations' });
45
+ if (isMixerConstruction(node)) sites.push({ start: node.getStart(source), end: node.getEnd(), wrapper: '__volterMixer' });
46
+ else if (isUseAnimations(node)) sites.push({ start: node.getStart(source), end: node.getEnd(), wrapper: '__volterAnimations' });
47
47
  ts.forEachChild(node, visit);
48
48
  };
49
49
  visit(source);
@@ -54,7 +54,7 @@ export function stampAnimation(code: string, file: string, relativeFile: string)
54
54
  const key = `${relativeFile}:${line + 1}:${character + 1}`;
55
55
  out = `${out.slice(0, site.start)}${site.wrapper}(${out.slice(site.start, site.end)}, ${JSON.stringify(key)})${out.slice(site.end)}`;
56
56
  }
57
- return `import { __vgaiMixer, __vgaiAnimations } from ${JSON.stringify(ANIMATION_LIVE_MODULE_ID)};\n${out}`;
57
+ return `import { __volterMixer, __volterAnimations } from ${JSON.stringify(ANIMATION_LIVE_MODULE_ID)};\n${out}`;
58
58
  }
59
59
 
60
60
  export function animationStampPlugin(services: AnimationServingServices): Plugin {
@@ -65,7 +65,7 @@ export function animationStampPlugin(services: AnimationServingServices): Plugin
65
65
  return roots.some((root) => file.startsWith(root + sep) || file.startsWith(root + '/'));
66
66
  };
67
67
  return {
68
- name: 'vgai-three-animation',
68
+ name: 'volter-three-animation',
69
69
  enforce: 'pre',
70
70
  resolveId(id) {
71
71
  return id === ANIMATION_LIVE_MODULE_ID ? VIRTUAL_ID : null;
package/serving/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `@volter/editor-threejs`'s server half (`package.json#vgai.serving`): the animation stamp that
2
+ * `@volter/editor-threejs`'s server half (`package.json#volter.serving`): the animation stamp that
3
3
  * lets the editor drive the mixers a project's own code makes, and the conversion of source model
4
4
  * formats to runtime GLB for the asset library's imports.
5
5
  */
@@ -102,7 +102,7 @@
102
102
  * ## What is NOT built-internal
103
103
  *
104
104
  * A node your game means as content — even one a class rather than JSX
105
- * constructs — is content. `vgaiBuiltInternal` is not "the editor cannot write
105
+ * constructs — is content. `volterBuiltInternal` is not "the editor cannot write
106
106
  * this"; that question is `TransformProvider.editability`'s, answered per
107
107
  * channel with a sentence. This mark answers "is this implementation", and
108
108
  * getting it wrong hides real content.
@@ -124,12 +124,12 @@ import { getObjectMark, setObjectMark } from '../ecs/object-marks';
124
124
  * the instance is already named by `node.name`, and the editor prints both.
125
125
  */
126
126
  export function markComponentRoot(node: THREE.Object3D, name: string): void {
127
- setObjectMark(node, 'vgaiComponentRoot', name);
127
+ setObjectMark(node, 'volterComponentRoot', name);
128
128
  }
129
129
 
130
130
  /** The component name `node` is the root of, or `undefined` for an ordinary node. */
131
131
  export function componentRootName(node: THREE.Object3D | null | undefined): string | undefined {
132
- const name = getObjectMark(node, 'vgaiComponentRoot');
132
+ const name = getObjectMark(node, 'volterComponentRoot');
133
133
  return typeof name === 'string' && name ? name : undefined;
134
134
  }
135
135
 
@@ -145,12 +145,12 @@ export function isComponentRoot(node: THREE.Object3D | null | undefined): boolea
145
145
  * the seam and not a sweep.
146
146
  */
147
147
  export function markBuiltInternal(node: THREE.Object3D): void {
148
- setObjectMark(node, 'vgaiBuiltInternal', true);
148
+ setObjectMark(node, 'volterBuiltInternal', true);
149
149
  }
150
150
 
151
151
  /** Whether `node` itself carries the implementation mark. Ancestry is the
152
152
  * CALLER's walk — see this module's header for why the mark is subtree-scoped
153
153
  * but not restamped onto descendants. */
154
154
  export function isBuiltInternal(node: THREE.Object3D | null | undefined): boolean {
155
- return getObjectMark(node, 'vgaiBuiltInternal') === true;
155
+ return getObjectMark(node, 'volterBuiltInternal') === true;
156
156
  }
@@ -17,7 +17,7 @@
17
17
  * that captures `(scene, camera, renderer)` on the first real frame.
18
18
  *
19
19
  * This is the hardened, typed form of the `ingest-study` spike
20
- * (`docs/ingest-study-spike/vgai-ingest-adapter.js`), proven against an
20
+ * (`docs/ingest-study-spike/volter-ingest-adapter.js`), proven against an
21
21
  * unmodified `three.js/examples/games_fps` game.
22
22
  *
23
23
  * DOM-backed addon renderers use ordinary prototype methods instead. The host
@@ -112,12 +112,12 @@ export interface SceneCaptureOptions {
112
112
  * Identity, not shape, is the discriminator: a host renderer and a game
113
113
  * renderer are the same class, both built after install, both drawing real
114
114
  * scenes. The host is the only party that knows which is which, so it says
115
- * so (`@vgai/threejs/viewport/renderer-ownership`).
115
+ * so (`@volter/threejs/viewport/renderer-ownership`).
116
116
  */
117
117
  isHostRenderer?: (renderer: unknown) => boolean;
118
118
  /**
119
119
  * The game's OWN declared world, read from its contract
120
- * (`window.vgaiGame` — the host passes a reader, never a cached value, because
120
+ * (`window.volterGame` — the host passes a reader, never a cached value, because
121
121
  * the contract is declared by the game's modules and may not exist yet when
122
122
  * the trap installs).
123
123
  *
@@ -136,7 +136,7 @@ export interface SceneCaptureOptions {
136
136
  * forever, and the real world that renders one frame later reaches no reader
137
137
  * at all. This is that reader. It never changes which world is adopted — it
138
138
  * makes the ambiguity a recorded fact (`packages/editor/src/world-adoption.ts`
139
- * publishes it to `vgai status`).
139
+ * publishes it to the editor's `status` command).
140
140
  *
141
141
  * Post-processing games legitimately render several (scene, camera) pairs per
142
142
  * frame, so alternates are INFORMATION, never an error. Host renders are
@@ -411,7 +411,7 @@ export function installSceneCapture(
411
411
 
412
412
  // Stash the real render fn per-instance under a unique symbol so multiple
413
413
  // renderers (editor's + game's) never collide.
414
- const REAL = Symbol('vgai.realRender');
414
+ const REAL = Symbol('volter.realRender');
415
415
 
416
416
  let captured: CapturedRuntime | null = null;
417
417
  let drawCount = 0;
@@ -439,7 +439,7 @@ export function installSceneCapture(
439
439
  // prototype getter/setter. The constructor's `this.setAnimationLoop = realFn` hits
440
440
  // our SETTER (the instance has no own property yet) and we stash realFn per-instance;
441
441
  // the GETTER returns a wrapper that records each non-null callback before forwarding.
442
- const REAL_SAL = Symbol('vgai.realSetAnimationLoop');
442
+ const REAL_SAL = Symbol('volter.realSetAnimationLoop');
443
443
  const loopCallbacks = new WeakMap<object, (time: number) => void>();
444
444
  const loopedRenderers = new Set<object>();
445
445
  /** Visibility clock of the in-flight `waitForCapture`, if any. */
@@ -788,7 +788,7 @@ export function installSceneCapture(
788
788
  waiters.push(wrapped);
789
789
  waitingVisibility = opts.visibility ?? documentVisibilityClock();
790
790
  opts.onWait?.(captureWindow);
791
- // A waiter that starts already-hidden (the normal `vgai play` path
791
+ // A waiter that starts already-hidden (the normal the editor's `play` command path
792
792
  // against a backgrounded tab) must not wait for a human to foreground
793
793
  // it. Pump any loop the game has already registered.
794
794
  queueMicrotask(pumpHiddenLoops);
@@ -28,7 +28,7 @@ export const CAMERA_ID = 'ingest:camera';
28
28
  /**
29
29
  * The editor parks its OWN objects — grid, its two lights, the particle
30
30
  * BatchedRenderer, every TransformControls/gizmo helper — on layer 31
31
- * (`@vgai/threejs/viewport/editor-layers`'s `EDITOR_LAYER`) so the game camera
31
+ * (`@volter/threejs/viewport/editor-layers`'s `EDITOR_LAYER`) so the game camera
32
32
  * never sees them. On an ingest root those objects are added to the GAME'S OWN
33
33
  * scene, which is the same tree this walk indexes.
34
34
  */
@@ -8,7 +8,7 @@
8
8
  * render while its tab is hidden, because the browser parks `requestAnimation
9
9
  * Frame` for a backgrounded document. The two facts together make one
10
10
  * deterministic failure: a tab that opens in the BACKGROUND (the normal human
11
- * path — `vgai edit` auto-opens a tab that routinely lands behind the current
11
+ * path — the editor's `edit` command auto-opens a tab that routinely lands behind the current
12
12
  * window) burns its whole capture window unable to draw, the deadline fires,
13
13
  * the mount dies terminally, and foregrounding the tab later changes nothing.
14
14
  * Agents, whose tabs happen to be visible, never saw it.
@@ -26,7 +26,7 @@
26
26
  * budget is not a failure — a human returning to the tab is what spends it —
27
27
  * and a cap would be exactly the boot-time clock this module exists to
28
28
  * remove. The parked wait is reported instead of being silent: see
29
- * `CaptureWaitObserver` in `scene-capture.ts` and `vgai status`'s
29
+ * `CaptureWaitObserver` in `scene-capture.ts` and the editor's `status` command's
30
30
  * `ingestCaptureWait`.
31
31
  *
32
32
  * The state machine is a pure function of (banked segments, now, hidden) so
@@ -223,7 +223,7 @@ export interface CaptureWaitOptions {
223
223
  *
224
224
  * A wait parked on a hidden tab is otherwise indistinguishable from a hung
225
225
  * mount: nothing renders, nothing fails, and every door reports silence.
226
- * This is the seam the editor publishes to `vgai status` so the answer is
226
+ * This is the seam the editor publishes to the editor's `status` command so the answer is
227
227
  * "waiting for the first visible frame — the tab is hidden", not a countdown
228
228
  * that is not running.
229
229
  */
@@ -128,7 +128,7 @@ export async function loadSplat(url: string, providedBytes?: Uint8Array): Promis
128
128
  const size = bounds.getSize(new THREE.Vector3()).multiplyScalar(1.5);
129
129
  const center = bounds.getCenter(new THREE.Vector3());
130
130
  const proxy = new THREE.Mesh(new THREE.BoxGeometry(size.x, size.y, size.z));
131
- proxy.name = '__vgai_splat_bounds';
131
+ proxy.name = '__volter_splat_bounds';
132
132
  proxy.position.copy(center);
133
133
  proxy.visible = false;
134
134
  proxy.raycast = () => {};
@@ -43,8 +43,8 @@ export interface ObjectMarkSchema {
43
43
  skeletonEnabled: boolean;
44
44
  engineInternal: boolean;
45
45
  editorHelper: boolean;
46
- vgaiComponentRoot: string;
47
- vgaiBuiltInternal: boolean;
46
+ volterComponentRoot: string;
47
+ volterBuiltInternal: boolean;
48
48
  }
49
49
 
50
50
  export const ObjectMarkKeys = {
@@ -53,8 +53,8 @@ export const ObjectMarkKeys = {
53
53
  skeletonEnabled: 'skeletonEnabled',
54
54
  engineInternal: 'engineInternal',
55
55
  editorHelper: 'editorHelper',
56
- vgaiComponentRoot: 'vgaiComponentRoot',
57
- vgaiBuiltInternal: 'vgaiBuiltInternal',
56
+ volterComponentRoot: 'volterComponentRoot',
57
+ volterBuiltInternal: 'volterBuiltInternal',
58
58
  } as const satisfies Record<keyof ObjectMarkSchema, string>;
59
59
 
60
60
  export function getObjectMark<K extends keyof ObjectMarkSchema>(
@@ -78,13 +78,13 @@
78
78
  *
79
79
  * Hierarchy-presentation convention (written by GAME code, read by the editor —
80
80
  * see `../adapter/hierarchy-marks.ts`, which is the ONLY place these two are
81
- * read/written from; the `vgai` prefix marks them as the HOST's namespace on a
81
+ * read/written from; the `volter` prefix marks them as the HOST's namespace on a
82
82
  * node a game owns, unlike every other key above, which the engine/editor also
83
83
  * write):
84
- * - `vgaiComponentRoot` — display name of the component instance this subtree
84
+ * - `volterComponentRoot` — display name of the component instance this subtree
85
85
  * IS. The node renders as one collapsed, expandable
86
86
  * row named for it.
87
- * - `vgaiBuiltInternal` — `true` on the ROOT of a subtree runtime code
87
+ * - `volterBuiltInternal` — `true` on the ROOT of a subtree runtime code
88
88
  * CONSTRUCTED rather than authored (skeleton bones,
89
89
  * particle renderers). Subtree-scoped: everything
90
90
  * below a marked node is built-internal too.
@@ -1,6 +1,6 @@
1
1
  /**
2
- * B8.4 — the Asset Lab COMPARE surface (`vgai screenshot <model.glb>
3
- * --compare <ref.glb>`): renders the project asset AND a caller-supplied reference GLB
2
+ * B8.4 — the Asset Lab COMPARE surface (the editor's `screenshot <model.glb>
3
+ * --compare <ref.glb>` command): renders the project asset AND a caller-supplied reference GLB
4
4
  * with matched orthographic front + side framing, then scores their
5
5
  * silhouettes (IoU) and composes review overlays, so an agent can
6
6
  * numerically converge a procedural character toward a reference.
@@ -118,7 +118,7 @@ export async function handleAssetPreviewCommand(
118
118
  };
119
119
  }
120
120
  if (compare !== undefined) {
121
- // B8.4 — the compare mode (`vgai screenshot <model.glb> --compare <ref.glb>`).
121
+ // B8.4 — the compare mode (the editor's `screenshot <model.glb> --compare <ref.glb>` command).
122
122
  // Validated here at the relay boundary so a malformed payload fails with
123
123
  // a named reason instead of a deep three.js error.
124
124
  if (shots !== undefined || shotSetDefinition !== undefined) {
@@ -142,7 +142,7 @@ export async function handleAssetPreviewCommand(
142
142
  // Wire-carried GLB bytes stand NOWHERE, so they take no scene stage and no
143
143
  // compare (whose reference is named some other way). An explicit `shotSet`
144
144
  // definition is a different matter and is served: a shot set stages the
145
- // subject itself, which is what lets `vgai screenshot <module> --orbit <n>`
145
+ // subject itself, which is what lets the editor's `screenshot <module> --orbit <n>` command
146
146
  // circle a model that only ever existed as bytes. `shots: 'source'` stays
147
147
  // out — it is the asset-path review set, keyed to a stored forward vector.
148
148
  if (typeof glbBase64 === 'string') {
@@ -2587,7 +2587,7 @@ export async function captureGlbBytesAssetPreview(
2587
2587
 
2588
2588
  /**
2589
2589
  * The same bytes, photographed as a LABELED SHOT SET instead of the four
2590
- * views — what `vgai screenshot <module> --orbit <n>` renders. A shot set
2590
+ * views — what the editor's `screenshot <module> --orbit <n>` command renders. A shot set
2591
2591
  * stages the subject itself, exactly the way the asset-path lane's
2592
2592
  * {@link captureShotSetModelPreview} does, so bytes are no less valid a
2593
2593
  * subject here than a project GLB is.
@@ -90,8 +90,8 @@ function instanceCallsiteOid(object: THREE.Object3D | null | undefined): string
90
90
  * Object3D (Drei cameras are the canonical example). It is a callsite address,
91
91
  * not the object's definition-side `userData.oid`. */
92
92
  function forwardedCallsiteOid(object: THREE.Object3D | null | undefined): string | undefined {
93
- const forwarded = (object as (THREE.Object3D & { __vgaiOid?: unknown }) | null | undefined)
94
- ?.__vgaiOid;
93
+ const forwarded = (object as (THREE.Object3D & { __volterOid?: unknown }) | null | undefined)
94
+ ?.__volterOid;
95
95
  return typeof forwarded === 'string' && forwarded ? forwarded : undefined;
96
96
  }
97
97
 
@@ -1920,7 +1920,7 @@ class SelectionOrigins extends THREE.Points<THREE.BufferGeometry, THREE.PointsMa
1920
1920
  toneMapped: false,
1921
1921
  }),
1922
1922
  );
1923
- this.name = 'vgai:selection-origins';
1923
+ this.name = 'volter:selection-origins';
1924
1924
  this.userData['editorHelper'] = true;
1925
1925
  this.renderOrder = 1000;
1926
1926
  this.frustumCulled = false;
@@ -138,7 +138,7 @@ export function isTransparentWrapper(object: THREE.Object3D): boolean {
138
138
  object.userData['oid'] === undefined &&
139
139
  getUserData(object, 'authoringInstance') === undefined &&
140
140
  getUserData(object, 'authoringRoot') !== true &&
141
- getUserData(object, 'vgaiComponentRoot') === undefined
141
+ getUserData(object, 'volterComponentRoot') === undefined
142
142
  );
143
143
  }
144
144
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Viewport pick context (B4, D12) — the camera/canvas seam that
3
- * `VgaiSceneAuthoringAdapter.pickable.pick` needs but cannot own itself: both
3
+ * `VolterSceneAuthoringAdapter.pickable.pick` needs but cannot own itself: both
4
4
  * live on `EditorViewport`, not on the adapter (the adapter only ever held a
5
5
  * `store` — see its own doc comment). A tiny module-level slot, same shape as
6
6
  * `./active-systems.ts`: `EditorViewport`'s constructor sets it once its
@@ -4,7 +4,7 @@
4
4
  * `editor-viewport.ts`'s former `_raycastEntity` so EVERY threejs-backed
5
5
  * authoring adapter whose live objects sit in `store.objectMap` reuses the
6
6
  * exact same logic:
7
- * - first-party `VgaiSceneAuthoringAdapter` (edit mode's focused world),
7
+ * - first-party `VolterSceneAuthoringAdapter` (edit mode's focused world),
8
8
  * - `ThreeAuthoringAdapter` (any live three tree — bare ingest
9
9
  * mode AND the three child of a multi-world PLAY composite).
10
10
  *
@@ -40,7 +40,7 @@ export function CameraInfo() {
40
40
  <EditorSurface
41
41
  variant="overlay"
42
42
  border
43
- className="vgai-camera-info vgai-chrome-island vgai-glass-island"
43
+ className="volter-camera-info volter-chrome-island volter-glass-island"
44
44
  data-island-scale="compact"
45
45
  >
46
46
  <Inline gap={8} align="center" style={{ whiteSpace: 'nowrap' }}>
@@ -39,7 +39,7 @@ export function InspectorObjectPreview({
39
39
  width: '100%',
40
40
  height: 220,
41
41
  minHeight: 220,
42
- borderBottom: '1px solid var(--vgai-structural-divider)',
42
+ borderBottom: '1px solid var(--volter-structural-divider)',
43
43
  overflow: 'hidden',
44
44
  position: 'relative',
45
45
  }
@@ -203,7 +203,7 @@ export function Object3DDocumentToolbar({
203
203
  if (!assetPath) return;
204
204
  setError(null);
205
205
  try {
206
- // The shell owns where a framing is RECORDED (`.vgai/thumbnails.json`,
206
+ // The shell owns where a framing is RECORDED (`.volter/thumbnails.json`,
207
207
  // written through the project-file route); this surface only knows the
208
208
  // asset and the pose. See `object3d-document-write-policy.ts`.
209
209
  await object3DDocumentWritePolicy().saveThumbnailFraming(
@@ -230,11 +230,11 @@ export function Object3DDocumentToolbar({
230
230
 
231
231
  const frameLabel = session.selection().length > 0 ? 'Frame selection' : 'Frame all';
232
232
  return (
233
- <div className="vgai-model-document-header">
233
+ <div className="volter-model-document-header">
234
234
  <EditorToolbar
235
235
  compact
236
236
  label="Viewport view controls"
237
- className="vgai-model-viewport-toolbar vgai-model-viewport-toolbar--view"
237
+ className="volter-model-viewport-toolbar volter-model-viewport-toolbar--view"
238
238
  >
239
239
  {/* THE BUTTON SAYS WHAT IT DOES. `session.frame()` frames the
240
240
  selection when there is one and the whole subject when there is
@@ -248,7 +248,7 @@ export function Object3DDocumentToolbar({
248
248
  <EditorIcon icon={faExpand} size="md" />
249
249
  </IconButton>
250
250
  </Tooltip>
251
- <div className="vgai-viewport-popover-anchor">
251
+ <div className="volter-viewport-popover-anchor">
252
252
  <Tooltip text="Camera orientation and projection">
253
253
  <Button
254
254
  ref={viewRef}
@@ -264,7 +264,7 @@ export function Object3DDocumentToolbar({
264
264
  aria-haspopup="menu"
265
265
  aria-expanded={viewOpen}
266
266
  onClick={() => setViewOpen((open) => !open)}
267
- className="vgai-model-toolbar-labelled-control"
267
+ className="volter-model-toolbar-labelled-control"
268
268
  >
269
269
  <EditorIcon icon={faCube} size="sm" />
270
270
  <span>
@@ -306,7 +306,7 @@ export function Object3DDocumentToolbar({
306
306
  setViewOpen(false);
307
307
  }}
308
308
  >
309
- <span className="vgai-menu-check">
309
+ <span className="volter-menu-check">
310
310
  {presentation.projection === projection && (
311
311
  <EditorIcon icon={faCheck} size="xs" />
312
312
  )}
@@ -338,7 +338,7 @@ export function Object3DDocumentToolbar({
338
338
  <EditorToolbar
339
339
  compact
340
340
  label="Viewport preview controls"
341
- className="vgai-model-viewport-toolbar vgai-model-viewport-toolbar--preview"
341
+ className="volter-model-viewport-toolbar volter-model-viewport-toolbar--preview"
342
342
  >
343
343
  {/* THE DISPLAY CONTROLS SIT AT THE TRAILING EDGE, which is where
344
344
  Blender's are: its 3D View header packs Visibility, Gizmo,
@@ -463,7 +463,7 @@ export function Object3DDocumentToolbar({
463
463
  }))),
464
464
  ]}
465
465
  />
466
- <div className="vgai-viewport-popover-anchor">
466
+ <div className="volter-viewport-popover-anchor">
467
467
  <Tooltip text="Asset preview actions">
468
468
  <IconButton
469
469
  ref={moreRef}
@@ -527,7 +527,7 @@ export function Object3DDocumentToolbar({
527
527
  </div>
528
528
  </EditorToolbar>
529
529
  {capture ? (
530
- <EditorPopover className="vgai-model-capture-preview">
530
+ <EditorPopover className="volter-model-capture-preview">
531
531
  <div>
532
532
  <Text as="strong" variant="label">
533
533
  Deterministic views
@@ -540,7 +540,7 @@ export function Object3DDocumentToolbar({
540
540
  </EditorPopover>
541
541
  ) : null}
542
542
  {error ? (
543
- <EditorBanner className="vgai-model-toolbar-error" tone="error">
543
+ <EditorBanner className="volter-model-toolbar-error" tone="error">
544
544
  {error}
545
545
  </EditorBanner>
546
546
  ) : null}