@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 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.0",
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
- // --- Project operations ---
288
+ // --- Registered project tools ---
289
289
 
290
- /** List live project-local operation definitions below `src/operations/`.
291
- * The editor server loads metadata in Node; operation modules never enter the
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 listProjectOperations(): Promise<ProjectOperationCatalog> {
294
- const res = await fetch(`${this.baseUrl}/__editor/project-operations`);
295
- if (!res.ok) throw new Error(`Failed to list project operations: ${res.status}`);
296
- return (await res.json()) as ProjectOperationCatalog;
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 operation through the existing validated
300
- * operation registry. Write/destructive operations require `confirm:true`. */
301
- async runProjectOperation(
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<ProjectOperationOutcome> {
306
- const res = await fetch(`${this.baseUrl}/__editor/project-operations/run`, {
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 ProjectOperationOutcome;
311
+ const body = (await res.json()) as ProjectToolOutcome;
312
312
  if (!body || typeof body !== 'object' || typeof body.ok !== 'boolean') {
313
- throw new Error(`Project operation returned an invalid response (${res.status}).`);
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: 'solid' | 'wireframe' | 'unlit';
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' | 'unlit';
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 ProjectOperationCatalogEntry {
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 interface ProjectOperationCatalog {
206
- operations: ProjectOperationCatalogEntry[];
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 ProjectOperationOutcome =
225
+ export type ProjectToolOutcome =
211
226
  | { ok: true; data: unknown }
212
227
  | {
213
228
  ok: false;