@vgai/editor-sdk 0.5.16 → 0.5.18

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@vgai/editor-sdk",
3
3
  "author": "Volter AI, Inc.",
4
4
  "license": "Apache-2.0",
5
- "version": "0.5.16",
5
+ "version": "0.5.18",
6
6
  "type": "module",
7
7
  "repository": {
8
8
  "type": "git",
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@types/three": "^0.180.0",
26
- "@vgai/sdk": "0.5.16"
26
+ "@vgai/sdk": "0.5.18"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "@vgai/engine": "*",
package/src/client.ts CHANGED
@@ -404,21 +404,11 @@ export class EditorClient {
404
404
  * `vgai eval` could recover these frames while `vgai screenshot` could not.
405
405
  * Off by default: a caller who does not ask must never be handed a frame
406
406
  * that only exists because the capture drove the game.
407
- *
408
- * `opts.devLayers` puts the game's DEV LAYERS (`dev: true` roots — its own
409
- * in-game dev GUI) INTO the frame. Also off by default, for the mirror-image
410
- * reason: a panel frame at the moment of a failure is strong evidence, and a
411
- * "does the game look right" frame with the panel painted over it is
412
- * worthless — so the contamination only happens when someone asks for it.
413
407
  */
414
- async captureGame(opts?: {
415
- refreshStarvedFrame?: boolean;
416
- devLayers?: boolean;
417
- }): Promise<GameCapture> {
408
+ async captureGame(opts?: { refreshStarvedFrame?: boolean }): Promise<GameCapture> {
418
409
  const data = await this.command<GameCapture>({
419
410
  type: 'bridge-screenshot',
420
411
  ...(opts?.refreshStarvedFrame === true ? { refreshStarvedFrame: true } : {}),
421
- ...(opts?.devLayers === true ? { devLayers: true } : {}),
422
412
  });
423
413
  const layers = data.layers;
424
414
  const flatness = data.flatness;
@@ -446,7 +436,6 @@ export class EditorClient {
446
436
  return this.command<GameplayRecordingStarted>({
447
437
  type: 'bridge-recording-start',
448
438
  ...(options.fps !== undefined ? { fps: options.fps } : {}),
449
- ...(options.devLayers === true ? { devLayers: true } : {}),
450
439
  });
451
440
  }
452
441
 
@@ -321,6 +321,28 @@ export interface ToolContributionSurfaces {
321
321
  readonly Object3DAuthoring: import('react').ComponentType<ToolObject3DAuthoringProps>;
322
322
  }
323
323
 
324
+ /**
325
+ * The live game a contribution is looking at, or `null` when nothing is
326
+ * playing.
327
+ *
328
+ * A dev-GUI contribution's whole subject is the RUNNING game — its stats,
329
+ * cheats, tuning handles and event stream all hang off the live `Game`, and
330
+ * there is no other door to it from a contribution (the editor's own state is
331
+ * not the game's). It is `unknown` deliberately: `@vgai/engine`'s `Game` is
332
+ * the project's dependency, not this package's, so a contribution narrows it
333
+ * with its own import rather than making every consumer of this SDK carry the
334
+ * engine's types.
335
+ *
336
+ * `instanceId` is the mount id the editor's runtime instruments are pointed
337
+ * at (the Inspect selector). With several seats live that is the ONLY thing
338
+ * distinguishing two mounts of the same project, so a contribution that
339
+ * caches per-game state keys it on this and re-reads when it changes.
340
+ */
341
+ export interface ToolContributionPlay {
342
+ readonly game: unknown;
343
+ readonly instanceId: string;
344
+ }
345
+
324
346
  export interface ToolContributionProps {
325
347
  /** The exact registered callable this contribution presents. */
326
348
  readonly tool: ProjectToolCatalogEntry;
@@ -332,13 +354,42 @@ export interface ToolContributionProps {
332
354
  readonly surfaces: ToolContributionSurfaces;
333
355
  /** Sanitized product-account projection. Never contains an access token. */
334
356
  readonly account: GenerationAccountProjection;
357
+ /** The inspected play instance, or `null` while nothing is playing. */
358
+ readonly play: ToolContributionPlay | null;
335
359
  /** Present when mounted as a workspace document contribution. */
336
360
  readonly documentId?: string;
337
361
  /** Whether that workspace document is the active center subject. */
338
362
  readonly active?: boolean;
339
363
  }
340
364
 
341
- export interface ToolInspectorContributionProps extends ToolContributionProps {
365
+ /**
366
+ * A `workspace.utility`'s props — the shared shape, except that `tool` may be
367
+ * absent.
368
+ *
369
+ * It is its own type rather than a relaxation of {@link ToolContributionProps}
370
+ * because only the two PRESENTING points earn the relaxation (this one and
371
+ * {@link ToolInspectorContributionProps}): a record-reading drawer panel (a
372
+ * log, a run timeline) presents what HAPPENED rather than one callable's
373
+ * output, so there is no honest name to put there and the loader stopped
374
+ * demanding a false one. Widening the shared props instead would hand every
375
+ * RUNNING contribution a `tool` it must now null-check while its own point
376
+ * still guarantees one.
377
+ */
378
+ export interface ToolUtilityContributionProps extends Omit<ToolContributionProps, 'tool'> {
379
+ /** The callable this utility declared, when it declared one at all. */
380
+ readonly tool?: ProjectToolCatalogEntry;
381
+ }
382
+
383
+ /**
384
+ * A `selection.inspector`'s props. `tool` is OPTIONAL here for the same reason
385
+ * it is on a utility: a section may present state the editor already has —
386
+ * readings, verbs a game registered as debug commands — and drive no single
387
+ * registered callable at all. A section that DOES commit through one still
388
+ * declares it and still gets the resolved entry.
389
+ */
390
+ export interface ToolInspectorContributionProps extends Omit<ToolContributionProps, 'tool'> {
391
+ /** The callable this section declared, when it declared one at all. */
392
+ readonly tool?: ProjectToolCatalogEntry;
342
393
  readonly node: ToolContributionNode | null;
343
394
  readonly nodeId: string | null;
344
395
  }
@@ -380,9 +431,31 @@ export type ToolGenerationResultContributionMatch = (
380
431
  result: unknown,
381
432
  ) => boolean;
382
433
 
434
+ /**
435
+ * What the inspector is showing AROUND the node a `selection.inspector`
436
+ * contribution is being matched against.
437
+ *
438
+ * It exists for one question a `node`/`adapter` pair cannot answer: with
439
+ * NOTHING selected, `node` is `null` on every surface alike — an open Asset
440
+ * Lab document's empty state and the play surface's Game subject are the same
441
+ * two arguments. A contribution that matches `node === null` therefore matched
442
+ * BOTH, and the empty-state subject of whatever document happened to be open
443
+ * grew sections belonging to another surface entirely.
444
+ *
445
+ * `nullSubjectId` is the id of the empty-state subject actually being composed
446
+ * (`inspection/null-subject.ts`), so a contribution scopes itself POSITIVELY —
447
+ * `ctx.nullSubjectId === 'game'` — rather than by guessing from the adapter.
448
+ * It is `null` whenever a node IS selected, which is the honest answer: there
449
+ * is no empty-state subject in that composition.
450
+ */
451
+ export interface ToolInspectorContributionMatchContext {
452
+ readonly nullSubjectId: string | null;
453
+ }
454
+
383
455
  /** Optional named export required by `selection.inspector` contributions. */
384
456
  export type ToolInspectorContributionMatch = (
385
457
  node: ToolContributionNode | null,
386
458
  /** Adapter-native API. Import its concrete type when a contribution needs it. */
387
459
  adapter: unknown,
460
+ context: ToolInspectorContributionMatchContext,
388
461
  ) => boolean;
package/src/types.ts CHANGED
@@ -104,9 +104,6 @@ export interface GameCapture {
104
104
  export interface GameplayRecordingOptions {
105
105
  /** Requested real-time capture cadence. Defaults to 30; range 1–60. */
106
106
  fps?: number;
107
- /** Include `dev: true` game layers. Off by default so ordinary evidence is
108
- * the player-visible game, not its debugging overlay. */
109
- devLayers?: boolean;
110
107
  }
111
108
 
112
109
  /** Facts fixed when a gameplay recording starts. */
@@ -385,6 +382,8 @@ export interface EditorState {
385
382
  activeViewportTab: ViewportTab;
386
383
  /** The actual active center document, including tool/source documents. */
387
384
  activeDocumentId?: string | null;
385
+ /** Every center document the editor currently has open, by stable registry id. */
386
+ openDocumentIds?: string[];
388
387
  activeTabKey: string;
389
388
  showGrid: boolean;
390
389
  showHelpers: boolean;
@@ -625,8 +624,6 @@ export interface EditorState {
625
624
  regions: {
626
625
  id: string;
627
626
  surface: string;
628
- /** true = this region grades the game's own dev layer, not shipped content. */
629
- dev: boolean;
630
627
  projector: string;
631
628
  dialect: string | null;
632
629
  anchors: string[];
@@ -661,11 +658,11 @@ export type TransformSpace = 'world' | 'local';
661
658
  * view. One runtime list owns both URL parsing and the public id type. */
662
659
  export const EDITOR_VIEW_WORKSPACE_DOCUMENT_IDS = [
663
660
  'workspace:scene',
661
+ 'workspace:canvas-scene',
664
662
  'workspace:game',
665
663
  'workspace:3d-components',
666
664
  'workspace:2d-components',
667
665
  'workspace:ui-components',
668
- 'workspace:dev',
669
666
  'workspace:build-profiles',
670
667
  'account',
671
668
  'project-tools',