@vgai/editor-sdk 0.5.42 → 0.5.44
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 +2 -2
- package/src/client.ts +324 -49
- package/src/contributions.ts +208 -1
- package/src/document-probe.ts +55 -2
- package/src/editor-view.ts +1 -0
- package/src/index.ts +14 -1
- package/src/types.ts +221 -11
package/src/types.ts
CHANGED
|
@@ -11,6 +11,16 @@ export type ViewportTab = 'edit' | 'play';
|
|
|
11
11
|
|
|
12
12
|
export type AssetKind = 'model' | 'image' | 'audio' | 'animation' | 'json' | 'prefab' | 'source';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* The editor's NAMED WORKSPACES — task-named layout memories over the one
|
|
16
|
+
* physical dock (ARCHITECTURE-CORE §Editor chrome). Named for the TASK, each
|
|
17
|
+
* borrowing the arrangement of the tool that does it best; `game` is the
|
|
18
|
+
* default and is the editor's standing arrangement. Restated here (rather than
|
|
19
|
+
* imported from the editor) for the same reason every other id union in this
|
|
20
|
+
* file is: the SDK is a wire client and must not depend on the editor bundle.
|
|
21
|
+
*/
|
|
22
|
+
export type EditorWorkspaceName = 'game' | 'model' | 'sculpt' | 'texture' | 'animate' | 'look';
|
|
23
|
+
|
|
14
24
|
export interface HelperVisibility {
|
|
15
25
|
bounds: boolean;
|
|
16
26
|
lights: boolean;
|
|
@@ -50,6 +60,30 @@ export interface ViewportCapture {
|
|
|
50
60
|
mimeType: 'image/png';
|
|
51
61
|
}
|
|
52
62
|
|
|
63
|
+
/**
|
|
64
|
+
* How an animated look move on the open Object3D document ended. Never an
|
|
65
|
+
* error: the camera is SHARED with the person watching, so "they grabbed it
|
|
66
|
+
* mid-orbit" is an outcome to read, not a failure to handle.
|
|
67
|
+
*/
|
|
68
|
+
export interface DocumentLookOutcome {
|
|
69
|
+
/** True only when the whole move was drawn. */
|
|
70
|
+
completed: boolean;
|
|
71
|
+
/** Why it stopped early: a human drag, a later look verb, or a closed document. */
|
|
72
|
+
cancelledBy?: 'human' | 'superseded' | 'closed';
|
|
73
|
+
/** Where the camera ended up, radians around the framed subject. */
|
|
74
|
+
azimuth: number;
|
|
75
|
+
/** Radians above the subject's horizon. */
|
|
76
|
+
elevation: number;
|
|
77
|
+
/** Seconds of the move that were actually drawn. */
|
|
78
|
+
seconds: number;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Where the open document's camera is standing and what it is aimed at. */
|
|
82
|
+
export interface DocumentCameraPose {
|
|
83
|
+
position: [number, number, number];
|
|
84
|
+
target: [number, number, number];
|
|
85
|
+
}
|
|
86
|
+
|
|
53
87
|
/** Result of the editor's native Asset Lab ragdoll-generation operation. */
|
|
54
88
|
export interface RagdollGenerationResult {
|
|
55
89
|
capability: 'added' | 'present';
|
|
@@ -98,6 +132,15 @@ export interface GameCapture {
|
|
|
98
132
|
/** True when the host loop was starved and the runtime rendered one
|
|
99
133
|
* deterministic tick to produce this frame. */
|
|
100
134
|
loopRecoveryFrame?: boolean;
|
|
135
|
+
/** Present when this frame came out of a RECORDED run (every `vgai play`
|
|
136
|
+
* records). The still is delivered either way; `notice` is the sentence
|
|
137
|
+
* naming the clip, its offset-0 wall clock, and what a still cannot answer —
|
|
138
|
+
* shown verbatim, never re-derived by the caller. */
|
|
139
|
+
recording?: {
|
|
140
|
+
path: string;
|
|
141
|
+
startedAt: string;
|
|
142
|
+
notice: string;
|
|
143
|
+
};
|
|
101
144
|
}
|
|
102
145
|
|
|
103
146
|
/** Options for recording the clean running-game composite. */
|
|
@@ -204,16 +247,61 @@ export type AssetPreviewSource =
|
|
|
204
247
|
*/
|
|
205
248
|
export type AssetPreviewStage = 'lab' | 'scene';
|
|
206
249
|
|
|
250
|
+
/**
|
|
251
|
+
* A free capture camera for the Asset Lab legs (`vgai screenshot`'s
|
|
252
|
+
* `--azimuth/--elevation/--distance`): ONE view from a chosen angle instead
|
|
253
|
+
* of the fixed four. Angles are relative to the subject's AUTHORED front —
|
|
254
|
+
* azimuth 0 photographs the declared front, 90 walks toward the side the
|
|
255
|
+
* turntable's yaw-90 shot shows; elevation raises the camera (degrees above
|
|
256
|
+
* level); `distance` is meters from the framing center, auto-fit when
|
|
257
|
+
* omitted.
|
|
258
|
+
*/
|
|
259
|
+
export interface AssetPreviewCameraChoice {
|
|
260
|
+
azimuthDegrees: number;
|
|
261
|
+
elevationDegrees: number;
|
|
262
|
+
distance?: number;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Pose an animated subject before capturing (`vgai screenshot`'s
|
|
267
|
+
* `--clip <name> --time <t>`): the named clip is sampled at `timeSeconds`
|
|
268
|
+
* on the capture's disposable snapshot — the source is never mutated. The
|
|
269
|
+
* capture fails loudly (naming the clips that DO exist) when the subject
|
|
270
|
+
* carries no clip by this name.
|
|
271
|
+
*/
|
|
272
|
+
export interface AssetPreviewPose {
|
|
273
|
+
clip: string;
|
|
274
|
+
timeSeconds: number;
|
|
275
|
+
}
|
|
276
|
+
|
|
207
277
|
export interface AssetPreviewOptions {
|
|
208
278
|
width?: number;
|
|
209
279
|
height?: number;
|
|
210
280
|
background?: AssetPreviewBackground;
|
|
211
281
|
stage?: AssetPreviewStage;
|
|
282
|
+
camera?: AssetPreviewCameraChoice;
|
|
283
|
+
pose?: AssetPreviewPose;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* How the captured subject was oriented relative to its AUTHORED coordinates.
|
|
288
|
+
* The editor yaw-normalizes a subject so the front camera photographs its
|
|
289
|
+
* declared front; a 180-degree yaw maps authored +X to screen-LEFT in the
|
|
290
|
+
* front view. The yaw is reported here (and stamped onto the images' own
|
|
291
|
+
* pixels as `+X>` / `<+X` markers) so it is never applied silently.
|
|
292
|
+
*/
|
|
293
|
+
export interface AssetPreviewOrientation {
|
|
294
|
+
/** The subject's declared forward, `[0,0,1]` when it declares none. */
|
|
295
|
+
forward: [number, number, number];
|
|
296
|
+
/** Yaw applied to face the front camera; 0 means authored axes = world axes. */
|
|
297
|
+
yawDegrees: number;
|
|
212
298
|
}
|
|
213
299
|
|
|
214
300
|
export interface AssetPreviewCapture {
|
|
215
301
|
width: number;
|
|
216
302
|
height: number;
|
|
303
|
+
/** Absent from editors that predate orientation reporting. */
|
|
304
|
+
orientation?: AssetPreviewOrientation;
|
|
217
305
|
views: Array<ViewportCapture & { view: AssetPreviewView }>;
|
|
218
306
|
contactSheet: ViewportCapture & { width: number; height: number };
|
|
219
307
|
}
|
|
@@ -231,6 +319,13 @@ export interface StoryCaptureOptions {
|
|
|
231
319
|
* because a UI story is not the Asset Lab's square 3D view. */
|
|
232
320
|
width?: number;
|
|
233
321
|
height?: number;
|
|
322
|
+
/** Free capture camera for THREE stories (same contract as the Asset Lab's
|
|
323
|
+
* {@link AssetPreviewCameraChoice}). A selected story that renders on the
|
|
324
|
+
* DOM leg refuses these BY NAME rather than silently ignoring them. */
|
|
325
|
+
camera?: AssetPreviewCameraChoice;
|
|
326
|
+
/** Clip pose for THREE stories (same contract as the Asset Lab's
|
|
327
|
+
* {@link AssetPreviewPose}); DOM-leg stories refuse it by name. */
|
|
328
|
+
pose?: AssetPreviewPose;
|
|
234
329
|
}
|
|
235
330
|
|
|
236
331
|
export interface StoryVariantImage extends ViewportCapture {
|
|
@@ -332,11 +427,27 @@ export interface ShotSetPoseMorph {
|
|
|
332
427
|
influence: number;
|
|
333
428
|
}
|
|
334
429
|
|
|
335
|
-
/**
|
|
430
|
+
/** The TRANSLATION channel of a pose: a joint displaced along its own local
|
|
431
|
+
* axis. Rotations alone cannot state a gait's vertical truth — a crouch, a
|
|
432
|
+
* jump apex, the hip dip that makes a walk read as weighted — because those
|
|
433
|
+
* are the root/hips MOVING, not a joint bending (round-4 finding: shot sets
|
|
434
|
+
* could not photograph a gait). Same delta semantics as the rotation: the
|
|
435
|
+
* capture engine applies `bone.translateX/Y/Z(meters)`, composing onto
|
|
436
|
+
* whatever local position the GLB baked. */
|
|
437
|
+
export interface ShotSetPoseTranslation {
|
|
438
|
+
bone: string;
|
|
439
|
+
axis: 'x' | 'y' | 'z';
|
|
440
|
+
/** A DELTA along the bone's own local axis, in meters, relative to the
|
|
441
|
+
* loaded GLB's baked rest position. */
|
|
442
|
+
meters: number;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/** One step of a named pose. A flat union rather than parallel lists: a
|
|
336
446
|
* single expression is normally one rotation AND one morph (a jaw ROTATION
|
|
337
447
|
* plus a brow MORPH), so keeping them in one ordered list means a definition
|
|
338
|
-
* never has to zip them.
|
|
339
|
-
|
|
448
|
+
* never has to zip them. Discriminated by field name: `radians` is a
|
|
449
|
+
* rotation, `meters` a translation, `influence` a morph. */
|
|
450
|
+
export type ShotSetPoseStep = ShotSetPoseRotation | ShotSetPoseMorph | ShotSetPoseTranslation;
|
|
340
451
|
|
|
341
452
|
export type ShotSetShot =
|
|
342
453
|
| { label: string; view: 'turntable'; yaw: number; pose?: string | undefined }
|
|
@@ -736,7 +847,14 @@ export interface EditorState {
|
|
|
736
847
|
}
|
|
737
848
|
|
|
738
849
|
export type ViewPreset = 'top' | 'front' | 'right' | 'perspective';
|
|
739
|
-
export type ShadingMode =
|
|
850
|
+
export type ShadingMode =
|
|
851
|
+
| 'solid'
|
|
852
|
+
| 'clay'
|
|
853
|
+
| 'unlit'
|
|
854
|
+
| 'wireframe'
|
|
855
|
+
| 'matcap'
|
|
856
|
+
| 'normals'
|
|
857
|
+
| 'overdraw';
|
|
740
858
|
|
|
741
859
|
/** One operation on the active native animation document's recorder. */
|
|
742
860
|
export type AnimationCaptureAction = 'start' | 'stop' | 'review' | 'commit' | 'discard';
|
|
@@ -841,6 +959,9 @@ export type EditorViewDocument =
|
|
|
841
959
|
| { kind: 'asset'; path: string; entityId?: never; assetKind?: AssetKind }
|
|
842
960
|
| { kind: 'asset'; entityId: string; path?: never; assetKind?: 'model' }
|
|
843
961
|
| { kind: 'tool'; id: string }
|
|
962
|
+
/** A document the adapter's table lists (a model, a page) — `id` is the
|
|
963
|
+
* table entry's id — opened in the editor registered for its kind. */
|
|
964
|
+
| { kind: 'document'; id: string }
|
|
844
965
|
| { kind: 'world'; id: string }
|
|
845
966
|
| { kind: 'story'; modulePath: string; storyName: string; mode?: 'preview' | 'docs' }
|
|
846
967
|
| { kind: 'project-tool'; name: string }
|
|
@@ -848,6 +969,15 @@ export type EditorViewDocument =
|
|
|
848
969
|
| {
|
|
849
970
|
kind: 'workspace';
|
|
850
971
|
id: EditorViewWorkspaceDocumentId;
|
|
972
|
+
/**
|
|
973
|
+
* For a COMPONENT BOARD document: the portable story frame to open on
|
|
974
|
+
* — a story id, or a unique CSF export name or label (an ambiguous or
|
|
975
|
+
* unknown value refuses loudly, listing candidates). Emitted back by
|
|
976
|
+
* the board's own presentation so a captured view round-trips. This is
|
|
977
|
+
* the design ledger's "board story selector": without it only the
|
|
978
|
+
* derived default story could ever be addressed.
|
|
979
|
+
*/
|
|
980
|
+
story?: string;
|
|
851
981
|
};
|
|
852
982
|
|
|
853
983
|
export interface EditorView {
|
|
@@ -871,9 +1001,36 @@ export interface PresentedEditorView {
|
|
|
871
1001
|
warnings: string[];
|
|
872
1002
|
}
|
|
873
1003
|
|
|
1004
|
+
/**
|
|
1005
|
+
* How big a capture comes back.
|
|
1006
|
+
*
|
|
1007
|
+
* A NUMBER is a square of that size, and square stays the default — an
|
|
1008
|
+
* unstaged look at a model is a square question. `{width, height}` is for the
|
|
1009
|
+
* shaped answer: a video-aspect frame that needs no crop afterwards, which is
|
|
1010
|
+
* what the model/module lanes' looks are actually for.
|
|
1011
|
+
*
|
|
1012
|
+
* Both are bounded by the EDITOR's own ceiling — 64..1024 per side, plus a
|
|
1013
|
+
* total no larger than a 1024 square. That is the relay budget, not a taste:
|
|
1014
|
+
* the pixels cross the editor relay as base64 JSON, and 1024 is where even
|
|
1015
|
+
* incompressible RGBA still fits its 50 MB request limit (`asset-preview.ts`'s
|
|
1016
|
+
* `MIN_SIZE`/`MAX_SIZE`). For more picture, take more views, not bigger ones.
|
|
1017
|
+
*/
|
|
1018
|
+
export type CaptureDimensions = number | { readonly width: number; readonly height: number };
|
|
1019
|
+
|
|
874
1020
|
/** The pixels of the active center document, with enough provenance for an
|
|
875
1021
|
* agent to prove which user-visible subject it captured. Editor chrome is
|
|
876
1022
|
* deliberately excluded. */
|
|
1023
|
+
/** A photograph of the editor PAGE — every panel as the person sees it
|
|
1024
|
+
* (`capture-editor-chrome`; the door that lets a skin, a workspace or a
|
|
1025
|
+
* contributed panel be judged sighted through the product). */
|
|
1026
|
+
export interface EditorChromeCapture extends ViewportCapture {
|
|
1027
|
+
view: EditorView;
|
|
1028
|
+
/** The page's on-screen size in CSS pixels — the frame's own size. */
|
|
1029
|
+
size: { width: number; height: number };
|
|
1030
|
+
layers: { canvases: number; domOverlays: number };
|
|
1031
|
+
flatness?: { degenerate: boolean; warning?: string };
|
|
1032
|
+
}
|
|
1033
|
+
|
|
877
1034
|
export interface ActiveDocumentCapture extends ViewportCapture {
|
|
878
1035
|
document: {
|
|
879
1036
|
id: string;
|
|
@@ -940,8 +1097,9 @@ export type {
|
|
|
940
1097
|
export type InspectionSurface = 'three' | 'canvas' | 'dom' | 'asset-lab';
|
|
941
1098
|
|
|
942
1099
|
/** Which LAYOUT the one inspector box is in: the compact box over the
|
|
943
|
-
* viewport,
|
|
944
|
-
|
|
1100
|
+
* viewport, the same sections stacked in the dock column, or that column
|
|
1101
|
+
* with the sections tabbed behind a vertical rail (`properties`). */
|
|
1102
|
+
export type InspectionPresentationKind = 'card' | 'column' | 'properties';
|
|
945
1103
|
|
|
946
1104
|
/** One inspected field: a stable scriptable `path` and the value at it. */
|
|
947
1105
|
export interface InspectedField {
|
|
@@ -965,10 +1123,15 @@ export interface InspectedField {
|
|
|
965
1123
|
|
|
966
1124
|
/** A section's content. Custom RENDERING remains opaque — the wire never
|
|
967
1125
|
* introspects React — while any ordinary descriptor channel that chrome owns
|
|
968
|
-
*
|
|
969
|
-
*
|
|
970
|
-
*
|
|
971
|
-
*
|
|
1126
|
+
* IS a `fields` body here, including its write-refusal reasons: nothing is
|
|
1127
|
+
* rendered on this wire, so naming chrome a reader cannot see while hiding
|
|
1128
|
+
* the fields it can use is the wrong half. (Measured: the whole react/DOM
|
|
1129
|
+
* lane draws its own widgets over the style descriptors, so every one of its
|
|
1130
|
+
* sections reported `custom` and `inspect()` enumerated zero fields for a DOM
|
|
1131
|
+
* element.) The two opaque kinds are distinguished because "this subject has
|
|
1132
|
+
* a live preview" is a real fact about it: `custom` is a contributed block
|
|
1133
|
+
* with no descriptor channel of its own, `preview` is the subject's own
|
|
1134
|
+
* square view of itself.
|
|
972
1135
|
*
|
|
973
1136
|
* A custom body carries `data` when it can say what it DISPLAYS — the keys
|
|
974
1137
|
* are the section's own vocabulary, not a shared schema. The shipped case is
|
|
@@ -982,7 +1145,6 @@ export type InspectedSectionBody =
|
|
|
982
1145
|
id: string;
|
|
983
1146
|
title: string;
|
|
984
1147
|
data?: Record<string, unknown>;
|
|
985
|
-
fields?: readonly InspectedField[];
|
|
986
1148
|
}
|
|
987
1149
|
| { kind: 'preview'; id: string; title: string };
|
|
988
1150
|
|
|
@@ -1076,6 +1238,54 @@ export interface InspectedFieldWrite {
|
|
|
1076
1238
|
write: InspectedWriteDestination;
|
|
1077
1239
|
}
|
|
1078
1240
|
|
|
1241
|
+
/**
|
|
1242
|
+
* The STRUCTURE verbs — the hierarchy context menu's own ops, addressable.
|
|
1243
|
+
*
|
|
1244
|
+
* The names are the menu's, not the provider's, because the menu is the
|
|
1245
|
+
* surface a human uses and an agent is doing the same thing through a
|
|
1246
|
+
* different door (`delete` covers the provider's `remove`/`removeMany`: a
|
|
1247
|
+
* multi-id delete is ONE undoable op when the adapter can batch it).
|
|
1248
|
+
*/
|
|
1249
|
+
export type StructureOp =
|
|
1250
|
+
| 'create'
|
|
1251
|
+
| 'delete'
|
|
1252
|
+
| 'duplicate'
|
|
1253
|
+
| 'reparent'
|
|
1254
|
+
| 'reorder'
|
|
1255
|
+
| 'wrap'
|
|
1256
|
+
| 'unwrap'
|
|
1257
|
+
| 'group'
|
|
1258
|
+
| 'ungroup'
|
|
1259
|
+
| 'copy'
|
|
1260
|
+
| 'cut'
|
|
1261
|
+
| 'paste';
|
|
1262
|
+
|
|
1263
|
+
/** Arguments for one {@link StructureOp}. Everything is optional: `id`/`ids`
|
|
1264
|
+
* default to the current selection, the menu's own subject. */
|
|
1265
|
+
export interface StructureOpOptions {
|
|
1266
|
+
id?: string;
|
|
1267
|
+
ids?: readonly string[];
|
|
1268
|
+
/** `create`: which creatable kind (see the adapter's `creatableKinds`). */
|
|
1269
|
+
kind?: string;
|
|
1270
|
+
/** `create`/`reparent`/`paste`: the destination; `null`/absent = document root. */
|
|
1271
|
+
parentId?: string;
|
|
1272
|
+
/** `reorder`: move immediately before this sibling; absent = to the end. */
|
|
1273
|
+
beforeSiblingId?: string;
|
|
1274
|
+
/** `wrap`: the wrapper tag; absent = the adapter's own default. */
|
|
1275
|
+
tag?: string;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
/** What one structure op answers. `write` is the same per-edit ack
|
|
1279
|
+
* `editor.setField()` carries — `persisted: false` means the tree moved and
|
|
1280
|
+
* no byte did. `id`/`ids` name what the op produced, when it produces one. */
|
|
1281
|
+
export interface StructureOpResult {
|
|
1282
|
+
id?: string | null;
|
|
1283
|
+
ids?: readonly string[];
|
|
1284
|
+
write?: InspectedWriteDestination;
|
|
1285
|
+
/** `copy` only: whether the clipboard actually took the payload. */
|
|
1286
|
+
copied?: boolean;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1079
1289
|
// ---------------------------------------------------------------- hierarchy
|
|
1080
1290
|
//
|
|
1081
1291
|
// The wire mirror of the editor's own `SerializedHierarchyPanel`
|