@vgai/cli 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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +111 -53
  3. package/package.json +8 -8
package/README.md CHANGED
@@ -42,7 +42,7 @@ vgai select <id> | --all | deselect selection
42
42
  vgai focus [id] | view <top|front|right|perspective>
43
43
  vgai show <viewport scene|game / inspector / console / build>
44
44
  vgai open-asset <path> <kind>
45
- vgai grid|helpers|stats <on|off> | shading <solid|wireframe|unlit>
45
+ vgai grid|helpers|stats <on|off> | shading <solid|unlit|wireframe|normals|overdraw>
46
46
  vgai status print full editor state as JSON
47
47
 
48
48
  vgai apply-diff <scene> <patch> [--report] apply a SceneDiff patch to a scene
package/dist/index.js CHANGED
@@ -261411,26 +261411,26 @@ var EditorClient = class {
261411
261411
  const data = await res.json();
261412
261412
  return data.projects;
261413
261413
  }
261414
- // --- Project operations ---
261415
- /** List live project-local operation definitions below `src/operations/`.
261416
- * The editor server loads metadata in Node; operation modules never enter the
261414
+ // --- Registered project tools ---
261415
+ /** List tools explicitly registered in `package.json#vgai.tools`.
261416
+ * The editor server loads callable metadata in Node; modules never enter the
261417
261417
  * editor browser merely because they were listed. */
261418
- async listProjectOperations() {
261419
- const res = await fetch(`${this.baseUrl}/__editor/project-operations`);
261420
- if (!res.ok) throw new Error(`Failed to list project operations: ${res.status}`);
261418
+ async listProjectTools() {
261419
+ const res = await fetch(`${this.baseUrl}/__editor/project-tools`);
261420
+ if (!res.ok) throw new Error(`Failed to list project tools: ${res.status}`);
261421
261421
  return await res.json();
261422
261422
  }
261423
- /** Execute one Node-hosted project operation through the existing validated
261424
- * operation registry. Write/destructive operations require `confirm:true`. */
261425
- async runProjectOperation(name, input = {}, options = {}) {
261426
- const res = await fetch(`${this.baseUrl}/__editor/project-operations/run`, {
261423
+ /** Execute one Node-hosted project tool through the shared validated
261424
+ * dispatcher. Write/destructive tools require `confirm:true`. */
261425
+ async runProjectTool(name, input = {}, options = {}) {
261426
+ const res = await fetch(`${this.baseUrl}/__editor/project-tools/run`, {
261427
261427
  method: "POST",
261428
261428
  headers: { "Content-Type": "application/json" },
261429
261429
  body: JSON.stringify({ name, input, confirm: options.confirm === true })
261430
261430
  });
261431
261431
  const body = await res.json();
261432
261432
  if (!body || typeof body !== "object" || typeof body.ok !== "boolean") {
261433
- throw new Error(`Project operation returned an invalid response (${res.status}).`);
261433
+ throw new Error(`Project tool returned an invalid response (${res.status}).`);
261434
261434
  }
261435
261435
  return body;
261436
261436
  }
@@ -275248,7 +275248,9 @@ var CORE_ERROR_CODES = {
275248
275248
  /** The impl threw something that isn't a declared, structured error. */
275249
275249
  INTERNAL_ERROR: "INTERNAL_ERROR"
275250
275250
  };
275251
+ var OPERATION_ERROR_BRAND = Symbol.for("@vgai/sdk.OperationError");
275251
275252
  var OperationError = class extends Error {
275253
+ [OPERATION_ERROR_BRAND] = true;
275252
275254
  code;
275253
275255
  data;
275254
275256
  constructor(code, message, data) {
@@ -275258,6 +275260,12 @@ var OperationError = class extends Error {
275258
275260
  this.data = data;
275259
275261
  }
275260
275262
  };
275263
+ function isOperationError(value) {
275264
+ if (value instanceof OperationError) return true;
275265
+ if (value === null || typeof value !== "object") return false;
275266
+ const candidate = value;
275267
+ return candidate[OPERATION_ERROR_BRAND] === true && typeof candidate["code"] === "string" && typeof candidate["message"] === "string";
275268
+ }
275261
275269
  function toStructuredIssues(issues) {
275262
275270
  return issues.map((issue2) => ({
275263
275271
  path: [...issue2.path],
@@ -275299,7 +275307,7 @@ function defineOperation(def) {
275299
275307
  return def;
275300
275308
  }
275301
275309
  function normalizeThrown(def, err2) {
275302
- if (err2 instanceof OperationError) {
275310
+ if (isOperationError(err2)) {
275303
275311
  const declared = def.errors.find((e) => e.code === err2.code);
275304
275312
  if (!declared) {
275305
275313
  return {
@@ -283487,6 +283495,54 @@ function registerManifestOperations(registry2) {
283487
283495
  registry2.register(projectManifestUpdate);
283488
283496
  }
283489
283497
 
283498
+ // ../vgai-sdk/src/project/provenance.ts
283499
+ var ProjectProvenanceOutputSchema = external_exports.object({
283500
+ path: external_exports.string(),
283501
+ bytes: external_exports.number().int().nonnegative(),
283502
+ sha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
283503
+ mediaType: external_exports.string().optional(),
283504
+ role: external_exports.enum(["asset", "prefab", "provenance", "other"]).optional()
283505
+ });
283506
+ var ProjectProvenanceExecutionSchema = external_exports.object({
283507
+ mode: external_exports.enum(["mock", "direct", "managed"]),
283508
+ provider: external_exports.string(),
283509
+ operation: external_exports.string().optional(),
283510
+ model: external_exports.string().optional(),
283511
+ requestId: external_exports.string().optional(),
283512
+ taskId: external_exports.string().optional(),
283513
+ managedJobId: external_exports.string().optional()
283514
+ });
283515
+ var ProjectProvenanceOperationSchema = external_exports.object({
283516
+ createdAt: external_exports.string().datetime(),
283517
+ operation: external_exports.object({
283518
+ name: external_exports.string(),
283519
+ source: external_exports.string().optional()
283520
+ }),
283521
+ execution: ProjectProvenanceExecutionSchema.optional(),
283522
+ executions: external_exports.array(ProjectProvenanceExecutionSchema).min(2).optional(),
283523
+ input: external_exports.json().optional(),
283524
+ outputs: external_exports.array(ProjectProvenanceOutputSchema).min(1)
283525
+ });
283526
+ var ProjectProvenanceDocumentSchema = external_exports.object({
283527
+ version: external_exports.literal(1),
283528
+ operations: external_exports.record(external_exports.string(), ProjectProvenanceOperationSchema)
283529
+ });
283530
+ var ProjectAttributionEntrySchema = external_exports.object({
283531
+ key: external_exports.string(),
283532
+ name: external_exports.string().optional(),
283533
+ source: external_exports.string().optional(),
283534
+ sourceUrl: external_exports.string().url().optional(),
283535
+ author: external_exports.string(),
283536
+ license: external_exports.string(),
283537
+ text: external_exports.string(),
283538
+ operationIds: external_exports.array(external_exports.string()),
283539
+ outputPaths: external_exports.array(external_exports.string())
283540
+ });
283541
+ var ProjectAttributionReportSchema = external_exports.object({
283542
+ version: external_exports.literal(1),
283543
+ entries: external_exports.array(ProjectAttributionEntrySchema)
283544
+ });
283545
+
283490
283546
  // ../vgai-sdk/src/project/index.ts
283491
283547
  function registerProjectOperations(registry2) {
283492
283548
  registerManifestOperations(registry2);
@@ -283584,7 +283640,7 @@ function writeScaffoldBaseline(targetDir, engineVersion, engineDir) {
283584
283640
  }
283585
283641
 
283586
283642
  // ../create-vgai-project/src/engine-version.ts
283587
- var SEMVER_RE2 = /^(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z-.]+)?(?:\+[0-9A-Za-z-.]+)?$/;
283643
+ var SEMVER_RE2 = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-.]+))?(?:\+([0-9A-Za-z-.]+))?$/;
283588
283644
  function parseSemver(version2) {
283589
283645
  const match = SEMVER_RE2.exec(version2);
283590
283646
  if (!match) return null;
@@ -283597,15 +283653,39 @@ function compareTuples(a, b) {
283597
283653
  }
283598
283654
  return 0;
283599
283655
  }
283656
+ function comparePrerelease(a, b) {
283657
+ if (a === b) return 0;
283658
+ if (a === void 0) return 1;
283659
+ if (b === void 0) return -1;
283660
+ const aParts = a.split(".");
283661
+ const bParts = b.split(".");
283662
+ for (let index = 0; index < Math.max(aParts.length, bParts.length); index++) {
283663
+ const aPart = aParts[index];
283664
+ const bPart = bParts[index];
283665
+ if (aPart === void 0) return -1;
283666
+ if (bPart === void 0) return 1;
283667
+ if (aPart === bPart) continue;
283668
+ const aNumeric = /^\d+$/.test(aPart);
283669
+ const bNumeric = /^\d+$/.test(bPart);
283670
+ if (aNumeric && bNumeric) return Number(aPart) < Number(bPart) ? -1 : 1;
283671
+ if (aNumeric !== bNumeric) return aNumeric ? -1 : 1;
283672
+ return aPart < bPart ? -1 : 1;
283673
+ }
283674
+ return 0;
283675
+ }
283600
283676
  function compareEnginePin(pin, current) {
283677
+ const pinMatch = SEMVER_RE2.exec(pin);
283678
+ const currentMatch = SEMVER_RE2.exec(current);
283601
283679
  const pinTuple = parseSemver(pin);
283602
283680
  const currentTuple = parseSemver(current);
283603
283681
  if (!pinTuple || !currentTuple) {
283604
283682
  const reason = !pinTuple && !currentTuple ? `neither pin "${pin}" nor current "${current}" is a valid exact semver string` : !pinTuple ? `pin "${pin}" is not a valid exact semver string` : `current "${current}" is not a valid exact semver string`;
283605
283683
  return { status: "invalid", pin, current, reason };
283606
283684
  }
283607
- const cmp = compareTuples(pinTuple, currentTuple);
283608
- const status = cmp === 0 ? "match" : cmp < 0 ? "pin-behind" : "pin-ahead";
283685
+ if (pin === current) return { status: "match", pin, current };
283686
+ const tupleCmp = compareTuples(pinTuple, currentTuple);
283687
+ const cmp = tupleCmp !== 0 ? tupleCmp : comparePrerelease(pinMatch?.[4], currentMatch?.[4]) || -1;
283688
+ const status = cmp < 0 ? "pin-behind" : "pin-ahead";
283609
283689
  return { status, pin, current };
283610
283690
  }
283611
283691
  function satisfiesRange(version2, range) {
@@ -284024,26 +284104,6 @@ test('React-only root mounts and receives honest DOM keyboard input', async ({ g
284024
284104
  await game.screenshot('react-root-after-keyboard-input');
284025
284105
  });
284026
284106
  `;
284027
- var REACT_ONLY_PLAYTEST_SOURCE = `import { editor, game } from '@vgai/live';
284028
-
284029
- await editor.play();
284030
- await game.waitFor(
284031
- (state) =>
284032
- (state('react-starter') as { lastInput?: string } | undefined)?.lastInput === 'Ready',
284033
- { simSeconds: 10 },
284034
- );
284035
- await game.page(async (page) => {
284036
- await page.keyboard.press('ArrowRight');
284037
- });
284038
- await game.waitFor(
284039
- (state) =>
284040
- (state('react-starter') as { lastInput?: string } | undefined)?.lastInput === 'ArrowRight',
284041
- { simSeconds: 10 },
284042
- );
284043
- const shot = await game.screenshot('react-playtest-after-keyboard-input');
284044
- console.log('React-only DOM input reached the game.');
284045
- console.log('screenshot: ' + shot);
284046
- `;
284047
284107
  var REACT_ONLY_MAIN_SOURCE = `import { manifestEntryModules } from 'virtual:vgai-manifest-entries';
284048
284108
  import { registerReactAdapter } from '@engine/react/root-adapter';
284049
284109
  import { mountGameFromManifest, type ManifestHost } from '@engine/runtime/mount-game';
@@ -284078,7 +284138,6 @@ function rewriteTemplateVariantFiles(targetDir, template) {
284078
284138
  if (template !== "react") return;
284079
284139
  rmSync(join15(targetDir, "src", "runtime"), { recursive: true, force: true });
284080
284140
  rmSync(join15(targetDir, "src", "scripts"), { recursive: true, force: true });
284081
- rmSync(join15(targetDir, "src", "tools"), { recursive: true, force: true });
284082
284141
  rmSync(join15(targetDir, "tests", "logic", "example.test.ts"), { force: true });
284083
284142
  rmSync(join15(targetDir, "public"), { recursive: true, force: true });
284084
284143
  mkdirSync4(join15(targetDir, "public"), { recursive: true });
@@ -284090,7 +284149,6 @@ function rewriteTemplateVariantFiles(targetDir, template) {
284090
284149
  REACT_ONLY_ACCEPTANCE_SOURCE,
284091
284150
  "utf-8"
284092
284151
  );
284093
- writeFileSync3(join15(targetDir, "scripts", "playtest.ts"), REACT_ONLY_PLAYTEST_SOURCE, "utf-8");
284094
284152
  }
284095
284153
  function rewriteTsconfig(targetDir, engineRelPath, editorRelPath) {
284096
284154
  const tsconfigPath = join15(targetDir, "tsconfig.json");
@@ -296607,8 +296665,8 @@ function defaultCreateDependencyMode() {
296607
296665
  return existsSync21(join25(ENGINE_ROOT, "packages", "engine")) ? "link" : "registry";
296608
296666
  }
296609
296667
  function cliVersion() {
296610
- if ("0.4.0") {
296611
- return "0.4.0";
296668
+ if ("0.4.1") {
296669
+ return "0.4.1";
296612
296670
  }
296613
296671
  try {
296614
296672
  const pkg = JSON.parse(readFileSync20(join25(__dirname4, "..", "package.json"), "utf8"));
@@ -296627,7 +296685,7 @@ function bakedTargetVersions() {
296627
296685
  if (false)
296628
296686
  return void 0;
296629
296687
  try {
296630
- return JSON.parse('{"@vgai/engine":"0.4.0","@vgai/editor":"0.4.0","@vgai/p2p-colyseus":"0.4.0","@vgai/probe":"0.4.0","@vgai/live":"0.4.0","@vgai/sdk":"0.4.0","@vgai/editor-sdk":"0.4.0","@vgai/cli":"0.4.0"}');
296688
+ return JSON.parse('{"@vgai/engine":"0.4.1","@vgai/editor":"0.4.1","@vgai/p2p-colyseus":"0.4.1","@vgai/probe":"0.4.1","@vgai/live":"0.4.1","@vgai/sdk":"0.4.1","@vgai/editor-sdk":"0.4.1","@vgai/cli":"0.4.1"}');
296631
296689
  } catch {
296632
296690
  return void 0;
296633
296691
  }
@@ -296717,7 +296775,7 @@ Project:
296717
296775
  run <name> Run a Node-hosted project capability with validated JSON input
296718
296776
  --describe Print the selected capability's schemas and metadata without running
296719
296777
  --input <file|-> Read input JSON from a file or stdin (default: {})
296720
- --yes Confirm write/destructive operation execution
296778
+ --yes Confirm write/destructive tool execution
296721
296779
  --json Print the full machine-readable catalog/outcome
296722
296780
  upgrade [folder] Report + re-sync + re-pin against this engine checkout (default: cwd)
296723
296781
  --report Report only \u2014 never write to disk
@@ -296890,7 +296948,7 @@ Display:
296890
296948
  grid <on|off> Set grid visibility
296891
296949
  helpers <on|off> Set helpers visibility
296892
296950
  stats <on|off> Set stats overlay
296893
- shading <mode> Set shading: solid, wireframe, unlit
296951
+ shading <mode> Set active viewport shading: solid, unlit, wireframe, normals, overdraw
296894
296952
 
296895
296953
  State:
296896
296954
  status Print full editor state
@@ -298555,12 +298613,12 @@ async function run() {
298555
298613
  console.error(usage);
298556
298614
  process.exit(EXIT_CODES.VALIDATION_ERROR);
298557
298615
  }
298558
- const catalog = await getClient().listProjectOperations();
298616
+ const catalog = await getClient().listProjectTools();
298559
298617
  if (runArgs.includes("--json")) {
298560
298618
  console.log(JSON.stringify(catalog, null, 2));
298561
298619
  break;
298562
298620
  }
298563
- for (const operation of catalog.operations) {
298621
+ for (const operation of catalog.tools) {
298564
298622
  console.log(
298565
298623
  `${operation.name} ${operation.host} ${operation.permission.risk} ${operation.summary}`
298566
298624
  );
@@ -298568,8 +298626,8 @@ async function run() {
298568
298626
  for (const error48 of catalog.loadErrors) {
298569
298627
  console.error(`\u2717 ${error48.sourcePath}: ${error48.message}`);
298570
298628
  }
298571
- if (catalog.operations.length === 0 && catalog.loadErrors.length === 0) {
298572
- console.log("No project operations found.");
298629
+ if (catalog.tools.length === 0 && catalog.loadErrors.length === 0) {
298630
+ console.log("No project tools found.");
298573
298631
  }
298574
298632
  break;
298575
298633
  }
@@ -298582,8 +298640,8 @@ async function run() {
298582
298640
  console.error(usage);
298583
298641
  process.exit(EXIT_CODES.VALIDATION_ERROR);
298584
298642
  }
298585
- const catalog = await getClient().listProjectOperations();
298586
- const operation = catalog.operations.find((entry) => entry.name === name);
298643
+ const catalog = await getClient().listProjectTools();
298644
+ const operation = catalog.tools.find((entry) => entry.name === name);
298587
298645
  if (!operation) {
298588
298646
  console.error(`No project capability is named ${JSON.stringify(name)}.`);
298589
298647
  process.exit(EXIT_CODES.VALIDATION_ERROR);
@@ -298618,12 +298676,12 @@ ${JSON.stringify(operation.resultSchema, null, 2)}`);
298618
298676
  );
298619
298677
  } catch (error48) {
298620
298678
  console.error(
298621
- `Invalid operation input JSON: ${error48 instanceof Error ? error48.message : error48}`
298679
+ `Invalid tool input JSON: ${error48 instanceof Error ? error48.message : error48}`
298622
298680
  );
298623
298681
  process.exit(EXIT_CODES.VALIDATION_ERROR);
298624
298682
  }
298625
298683
  }
298626
- const outcome = await getClient().runProjectOperation(name, input, {
298684
+ const outcome = await getClient().runProjectTool(name, input, {
298627
298685
  confirm: runArgs.includes("--yes")
298628
298686
  });
298629
298687
  console.log(JSON.stringify(outcome, null, 2));
@@ -299375,11 +299433,11 @@ Choose exactly one target: project, --port, or --all.`);
299375
299433
  break;
299376
299434
  case "shading":
299377
299435
  if (hasHelpFlag(args)) {
299378
- console.log("Usage: vgai shading <solid|wireframe|unlit>");
299436
+ console.log("Usage: vgai shading <solid|unlit|wireframe|normals|overdraw>");
299379
299437
  break;
299380
299438
  }
299381
- if (!args[1]) {
299382
- console.error("Usage: vgai shading <solid|wireframe|unlit>");
299439
+ if (!["solid", "unlit", "wireframe", "normals", "overdraw"].includes(args[1] ?? "")) {
299440
+ console.error("Usage: vgai shading <solid|unlit|wireframe|normals|overdraw>");
299383
299441
  process.exit(1);
299384
299442
  }
299385
299443
  await getClient().setShadingMode(args[1]);
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@vgai/cli",
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",
@@ -28,13 +28,13 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@oclif/core": "^4.11.14",
31
- "@vgai/editor": "0.4.0",
32
- "@vgai/editor-sdk": "0.4.0",
33
- "@vgai/engine": "0.4.0",
34
- "@vgai/live": "0.4.0",
35
- "@vgai/p2p-colyseus": "0.4.0",
36
- "@vgai/probe": "0.4.0",
37
- "@vgai/sdk": "0.4.0",
31
+ "@vgai/editor": "0.4.1",
32
+ "@vgai/editor-sdk": "0.4.1",
33
+ "@vgai/engine": "0.4.1",
34
+ "@vgai/live": "0.4.1",
35
+ "@vgai/p2p-colyseus": "0.4.1",
36
+ "@vgai/probe": "0.4.1",
37
+ "@vgai/sdk": "0.4.1",
38
38
  "ink": "^7.1.0",
39
39
  "playwright": "^1.58.2",
40
40
  "react": "^19.2.4",