@vgai/editor-sdk 0.4.0 → 0.4.1
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/README.md +37 -2
- package/package.json +3 -2
- package/src/client.ts +16 -16
- package/src/contributions.ts +39 -0
- package/src/index.ts +10 -3
- package/src/types.ts +21 -6
package/README.md
CHANGED
|
@@ -30,17 +30,52 @@ One export, `EditorClient`, plus its types (`EditorState`, `ProjectInfo`,
|
|
|
30
30
|
and three-quarter captures of a project model or authored entity hierarchy
|
|
31
31
|
- Panels: `showViewport('scene'|'game')`, `showInspector`, `openAsset`,
|
|
32
32
|
`closeAsset`, `toggleConsole`, `toggleCommandPalette`, `showBuild`
|
|
33
|
-
- Display: `setGrid`, `setHelpers`, `setStats`, `setShadingMode`,
|
|
34
|
-
`setHelperType`
|
|
33
|
+
- Display: `setGrid`, `setHelpers`, `setStats`, `setShadingMode` (`solid`,
|
|
34
|
+
`unlit`, `wireframe`, `normals`, or `overdraw`), `setHelperType` (including
|
|
35
|
+
the independent `bounds` category). Shading targets the active Scene/Game
|
|
36
|
+
viewport and remains render-only, session-local state.
|
|
35
37
|
- Transform tools: `setTransformMode`, `setTransformSpace`, `setSnap`
|
|
36
38
|
- Scene/project: `openScene`, `createProject`, `openProject`, `getProject`,
|
|
37
39
|
`listRecentProjects`
|
|
38
40
|
- State/logs: `getState`, `waitForState(predicate, timeoutMs)`,
|
|
39
41
|
`getLogEntries`
|
|
42
|
+
- Project tools: `listProjectTools`, `runProjectTool`
|
|
40
43
|
|
|
41
44
|
Commands throw on `{ ok: false }` responses, including the server's timeout
|
|
42
45
|
when no browser editor is connected — failures are never silently swallowed.
|
|
43
46
|
|
|
47
|
+
### Editor contributions for project tools
|
|
48
|
+
|
|
49
|
+
An optional React contribution is a normal default-exported component. Import
|
|
50
|
+
its props from `@vgai/editor-sdk/contributions`; the editor supplies the exact
|
|
51
|
+
registered tool and an already-configured client:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { Button } from '@editor/widgets';
|
|
55
|
+
import type { ToolContributionProps } from '@vgai/editor-sdk/contributions';
|
|
56
|
+
|
|
57
|
+
export default function MapBuilder({ tool, client }: ToolContributionProps) {
|
|
58
|
+
return (
|
|
59
|
+
<Button
|
|
60
|
+
variant="solid"
|
|
61
|
+
onClick={() => void client.runProjectTool(tool.name, { seed: 42 }, { confirm: true })}
|
|
62
|
+
>
|
|
63
|
+
Build map
|
|
64
|
+
</Button>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The package registration chooses `workspace.document`, `workspace.utility`, or
|
|
70
|
+
`selection.inspector`. Inspector contributions additionally receive
|
|
71
|
+
`node`/`nodeId` and export `match(node, adapter)`. There is no extension class,
|
|
72
|
+
lifecycle, or proprietary UI description.
|
|
73
|
+
|
|
74
|
+
Use ordinary React/CSS for composition and `@editor/widgets` for controls.
|
|
75
|
+
Shape the UI for its contribution point: a bounded workspace for documents, a
|
|
76
|
+
dense single column for inspector sections, and a compact row/status block for
|
|
77
|
+
utilities. Badges are for short statuses and counts, not headings.
|
|
78
|
+
|
|
44
79
|
### Asset Lab capture
|
|
45
80
|
|
|
46
81
|
`captureAssetPreview` accepts exactly one source: an authored entity hierarchy
|
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.4.
|
|
5
|
+
"version": "0.4.1",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"src"
|
|
17
17
|
],
|
|
18
18
|
"exports": {
|
|
19
|
-
".": "./src/index.ts"
|
|
19
|
+
".": "./src/index.ts",
|
|
20
|
+
"./contributions": "./src/contributions.ts"
|
|
20
21
|
}
|
|
21
22
|
}
|
package/src/client.ts
CHANGED
|
@@ -7,9 +7,9 @@ import type {
|
|
|
7
7
|
GameCapture,
|
|
8
8
|
HelperVisibility,
|
|
9
9
|
ProjectInfo,
|
|
10
|
-
ProjectOperationCatalog,
|
|
11
|
-
ProjectOperationOutcome,
|
|
12
10
|
ProjectTemplate,
|
|
11
|
+
ProjectToolCatalog,
|
|
12
|
+
ProjectToolOutcome,
|
|
13
13
|
RecentProject,
|
|
14
14
|
ShadingMode,
|
|
15
15
|
TransformMode,
|
|
@@ -285,32 +285,32 @@ export class EditorClient {
|
|
|
285
285
|
return data.projects;
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
-
// ---
|
|
288
|
+
// --- Registered project tools ---
|
|
289
289
|
|
|
290
|
-
/** List
|
|
291
|
-
* The editor server loads metadata in Node;
|
|
290
|
+
/** List tools explicitly registered in `package.json#vgai.tools`.
|
|
291
|
+
* The editor server loads callable metadata in Node; modules never enter the
|
|
292
292
|
* editor browser merely because they were listed. */
|
|
293
|
-
async
|
|
294
|
-
const res = await fetch(`${this.baseUrl}/__editor/project-
|
|
295
|
-
if (!res.ok) throw new Error(`Failed to list project
|
|
296
|
-
return (await res.json()) as
|
|
293
|
+
async listProjectTools(): Promise<ProjectToolCatalog> {
|
|
294
|
+
const res = await fetch(`${this.baseUrl}/__editor/project-tools`);
|
|
295
|
+
if (!res.ok) throw new Error(`Failed to list project tools: ${res.status}`);
|
|
296
|
+
return (await res.json()) as ProjectToolCatalog;
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
-
/** Execute one Node-hosted project
|
|
300
|
-
*
|
|
301
|
-
async
|
|
299
|
+
/** Execute one Node-hosted project tool through the shared validated
|
|
300
|
+
* dispatcher. Write/destructive tools require `confirm:true`. */
|
|
301
|
+
async runProjectTool(
|
|
302
302
|
name: string,
|
|
303
303
|
input: unknown = {},
|
|
304
304
|
options: { confirm?: boolean } = {},
|
|
305
|
-
): Promise<
|
|
306
|
-
const res = await fetch(`${this.baseUrl}/__editor/project-
|
|
305
|
+
): Promise<ProjectToolOutcome> {
|
|
306
|
+
const res = await fetch(`${this.baseUrl}/__editor/project-tools/run`, {
|
|
307
307
|
method: 'POST',
|
|
308
308
|
headers: { 'Content-Type': 'application/json' },
|
|
309
309
|
body: JSON.stringify({ name, input, confirm: options.confirm === true }),
|
|
310
310
|
});
|
|
311
|
-
const body = (await res.json()) as
|
|
311
|
+
const body = (await res.json()) as ProjectToolOutcome;
|
|
312
312
|
if (!body || typeof body !== 'object' || typeof body.ok !== 'boolean') {
|
|
313
|
-
throw new Error(`Project
|
|
313
|
+
throw new Error(`Project tool returned an invalid response (${res.status}).`);
|
|
314
314
|
}
|
|
315
315
|
return body;
|
|
316
316
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Props for ordinary React components registered at editor contribution
|
|
3
|
+
* points. There is deliberately no extension class or lifecycle: package
|
|
4
|
+
* metadata names a module and the editor renders its default export.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { EditorClient } from './client.js';
|
|
8
|
+
import type { ProjectToolCatalogEntry } from './types.js';
|
|
9
|
+
|
|
10
|
+
/** Stable, format-neutral selection data available to inspector contributions. */
|
|
11
|
+
export interface ToolContributionNode {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly label: string;
|
|
14
|
+
readonly role?: string;
|
|
15
|
+
readonly secondaryLabel?: string;
|
|
16
|
+
readonly kind: string;
|
|
17
|
+
readonly parentId: string | null;
|
|
18
|
+
readonly childIds: string[];
|
|
19
|
+
readonly flags: object;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ToolContributionProps {
|
|
23
|
+
/** The exact registered callable this contribution presents. */
|
|
24
|
+
readonly tool: ProjectToolCatalogEntry;
|
|
25
|
+
/** Direct editor SDK client; invoke with `client.runProjectTool(tool.name, ...)`. */
|
|
26
|
+
readonly client: EditorClient;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface ToolInspectorContributionProps extends ToolContributionProps {
|
|
30
|
+
readonly node: ToolContributionNode | null;
|
|
31
|
+
readonly nodeId: string | null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Optional named export required by `selection.inspector` contributions. */
|
|
35
|
+
export type ToolInspectorContributionMatch = (
|
|
36
|
+
node: ToolContributionNode | null,
|
|
37
|
+
/** Adapter-native API. Import its concrete type when a contribution needs it. */
|
|
38
|
+
adapter: unknown,
|
|
39
|
+
) => boolean;
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
export { EditorClient } from './client.js';
|
|
2
|
+
export type {
|
|
3
|
+
ToolContributionNode,
|
|
4
|
+
ToolContributionProps,
|
|
5
|
+
ToolInspectorContributionMatch,
|
|
6
|
+
ToolInspectorContributionProps,
|
|
7
|
+
} from './contributions.js';
|
|
2
8
|
export type {
|
|
3
9
|
AssetKind,
|
|
4
10
|
AssetPreviewBackground,
|
|
@@ -12,10 +18,11 @@ export type {
|
|
|
12
18
|
GameCapture,
|
|
13
19
|
HelperVisibility,
|
|
14
20
|
ProjectInfo,
|
|
15
|
-
ProjectOperationCatalog,
|
|
16
|
-
ProjectOperationCatalogEntry,
|
|
17
|
-
ProjectOperationOutcome,
|
|
18
21
|
ProjectTemplate,
|
|
22
|
+
ProjectToolCatalog,
|
|
23
|
+
ProjectToolCatalogEntry,
|
|
24
|
+
ProjectToolContribution,
|
|
25
|
+
ProjectToolOutcome,
|
|
19
26
|
RecentProject,
|
|
20
27
|
ShadingMode,
|
|
21
28
|
TransformMode,
|
package/src/types.ts
CHANGED
|
@@ -9,6 +9,7 @@ export type AssetKind =
|
|
|
9
9
|
| 'material';
|
|
10
10
|
|
|
11
11
|
export interface HelperVisibility {
|
|
12
|
+
bounds: boolean;
|
|
12
13
|
lights: boolean;
|
|
13
14
|
cameras: boolean;
|
|
14
15
|
colliders: boolean;
|
|
@@ -103,7 +104,7 @@ export interface EditorState {
|
|
|
103
104
|
showGrid: boolean;
|
|
104
105
|
showHelpers: boolean;
|
|
105
106
|
showStats: boolean;
|
|
106
|
-
shadingMode:
|
|
107
|
+
shadingMode: ShadingMode;
|
|
107
108
|
helperVisibility: HelperVisibility;
|
|
108
109
|
transformMode: 'translate' | 'rotate' | 'scale';
|
|
109
110
|
transformSpace: 'world' | 'local';
|
|
@@ -167,7 +168,7 @@ export interface EditorState {
|
|
|
167
168
|
}
|
|
168
169
|
|
|
169
170
|
export type ViewPreset = 'top' | 'front' | 'right' | 'perspective';
|
|
170
|
-
export type ShadingMode = 'solid' | 'wireframe' | '
|
|
171
|
+
export type ShadingMode = 'solid' | 'unlit' | 'wireframe' | 'normals' | 'overdraw';
|
|
171
172
|
export type TransformMode = 'translate' | 'rotate' | 'scale';
|
|
172
173
|
export type TransformSpace = 'world' | 'local';
|
|
173
174
|
|
|
@@ -186,7 +187,7 @@ export interface RecentProject {
|
|
|
186
187
|
thumbnail?: string;
|
|
187
188
|
}
|
|
188
189
|
|
|
189
|
-
export interface
|
|
190
|
+
export interface ProjectToolCatalogEntry {
|
|
190
191
|
name: string;
|
|
191
192
|
summary: string;
|
|
192
193
|
description: string;
|
|
@@ -200,14 +201,28 @@ export interface ProjectOperationCatalogEntry {
|
|
|
200
201
|
supportsDryRun: boolean;
|
|
201
202
|
longRunning: boolean;
|
|
202
203
|
permission: { risk: 'read' | 'write' | 'destructive'; summary: string };
|
|
204
|
+
contributions: ProjectToolContribution[];
|
|
203
205
|
}
|
|
204
206
|
|
|
205
|
-
export
|
|
206
|
-
|
|
207
|
+
export type ToolContributionPoint =
|
|
208
|
+
| 'workspace.document'
|
|
209
|
+
| 'selection.inspector'
|
|
210
|
+
| 'workspace.utility';
|
|
211
|
+
|
|
212
|
+
export interface ProjectToolContribution {
|
|
213
|
+
id: string;
|
|
214
|
+
point: ToolContributionPoint;
|
|
215
|
+
title: string;
|
|
216
|
+
/** Project-relative or package-absolute browser module path. */
|
|
217
|
+
entryPath: string;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface ProjectToolCatalog {
|
|
221
|
+
tools: ProjectToolCatalogEntry[];
|
|
207
222
|
loadErrors: Array<{ sourcePath: string; message: string }>;
|
|
208
223
|
}
|
|
209
224
|
|
|
210
|
-
export type
|
|
225
|
+
export type ProjectToolOutcome =
|
|
211
226
|
| { ok: true; data: unknown }
|
|
212
227
|
| {
|
|
213
228
|
ok: false;
|