@vgai/cli 0.4.1-canary.20260715.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 +1 -1
- package/dist/index.js +63 -53
- 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|
|
|
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
|
-
// ---
|
|
261415
|
-
/** List
|
|
261416
|
-
* The editor server loads metadata in Node;
|
|
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
|
|
261419
|
-
const res = await fetch(`${this.baseUrl}/__editor/project-
|
|
261420
|
-
if (!res.ok) throw new Error(`Failed to list project
|
|
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
|
|
261424
|
-
*
|
|
261425
|
-
async
|
|
261426
|
-
const res = await fetch(`${this.baseUrl}/__editor/project-
|
|
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
|
|
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
|
|
275310
|
+
if (isOperationError(err2)) {
|
|
275303
275311
|
const declared = def.errors.find((e) => e.code === err2.code);
|
|
275304
275312
|
if (!declared) {
|
|
275305
275313
|
return {
|
|
@@ -283632,7 +283640,7 @@ function writeScaffoldBaseline(targetDir, engineVersion, engineDir) {
|
|
|
283632
283640
|
}
|
|
283633
283641
|
|
|
283634
283642
|
// ../create-vgai-project/src/engine-version.ts
|
|
283635
|
-
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-.]+))?$/;
|
|
283636
283644
|
function parseSemver(version2) {
|
|
283637
283645
|
const match = SEMVER_RE2.exec(version2);
|
|
283638
283646
|
if (!match) return null;
|
|
@@ -283645,15 +283653,39 @@ function compareTuples(a, b) {
|
|
|
283645
283653
|
}
|
|
283646
283654
|
return 0;
|
|
283647
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
|
+
}
|
|
283648
283676
|
function compareEnginePin(pin, current) {
|
|
283677
|
+
const pinMatch = SEMVER_RE2.exec(pin);
|
|
283678
|
+
const currentMatch = SEMVER_RE2.exec(current);
|
|
283649
283679
|
const pinTuple = parseSemver(pin);
|
|
283650
283680
|
const currentTuple = parseSemver(current);
|
|
283651
283681
|
if (!pinTuple || !currentTuple) {
|
|
283652
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`;
|
|
283653
283683
|
return { status: "invalid", pin, current, reason };
|
|
283654
283684
|
}
|
|
283655
|
-
|
|
283656
|
-
const
|
|
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";
|
|
283657
283689
|
return { status, pin, current };
|
|
283658
283690
|
}
|
|
283659
283691
|
function satisfiesRange(version2, range) {
|
|
@@ -284072,26 +284104,6 @@ test('React-only root mounts and receives honest DOM keyboard input', async ({ g
|
|
|
284072
284104
|
await game.screenshot('react-root-after-keyboard-input');
|
|
284073
284105
|
});
|
|
284074
284106
|
`;
|
|
284075
|
-
var REACT_ONLY_PLAYTEST_SOURCE = `import { editor, game } from '@vgai/live';
|
|
284076
|
-
|
|
284077
|
-
await editor.play();
|
|
284078
|
-
await game.waitFor(
|
|
284079
|
-
(state) =>
|
|
284080
|
-
(state('react-starter') as { lastInput?: string } | undefined)?.lastInput === 'Ready',
|
|
284081
|
-
{ simSeconds: 10 },
|
|
284082
|
-
);
|
|
284083
|
-
await game.page(async (page) => {
|
|
284084
|
-
await page.keyboard.press('ArrowRight');
|
|
284085
|
-
});
|
|
284086
|
-
await game.waitFor(
|
|
284087
|
-
(state) =>
|
|
284088
|
-
(state('react-starter') as { lastInput?: string } | undefined)?.lastInput === 'ArrowRight',
|
|
284089
|
-
{ simSeconds: 10 },
|
|
284090
|
-
);
|
|
284091
|
-
const shot = await game.screenshot('react-playtest-after-keyboard-input');
|
|
284092
|
-
console.log('React-only DOM input reached the game.');
|
|
284093
|
-
console.log('screenshot: ' + shot);
|
|
284094
|
-
`;
|
|
284095
284107
|
var REACT_ONLY_MAIN_SOURCE = `import { manifestEntryModules } from 'virtual:vgai-manifest-entries';
|
|
284096
284108
|
import { registerReactAdapter } from '@engine/react/root-adapter';
|
|
284097
284109
|
import { mountGameFromManifest, type ManifestHost } from '@engine/runtime/mount-game';
|
|
@@ -284126,7 +284138,6 @@ function rewriteTemplateVariantFiles(targetDir, template) {
|
|
|
284126
284138
|
if (template !== "react") return;
|
|
284127
284139
|
rmSync(join15(targetDir, "src", "runtime"), { recursive: true, force: true });
|
|
284128
284140
|
rmSync(join15(targetDir, "src", "scripts"), { recursive: true, force: true });
|
|
284129
|
-
rmSync(join15(targetDir, "src", "tools"), { recursive: true, force: true });
|
|
284130
284141
|
rmSync(join15(targetDir, "tests", "logic", "example.test.ts"), { force: true });
|
|
284131
284142
|
rmSync(join15(targetDir, "public"), { recursive: true, force: true });
|
|
284132
284143
|
mkdirSync4(join15(targetDir, "public"), { recursive: true });
|
|
@@ -284138,7 +284149,6 @@ function rewriteTemplateVariantFiles(targetDir, template) {
|
|
|
284138
284149
|
REACT_ONLY_ACCEPTANCE_SOURCE,
|
|
284139
284150
|
"utf-8"
|
|
284140
284151
|
);
|
|
284141
|
-
writeFileSync3(join15(targetDir, "scripts", "playtest.ts"), REACT_ONLY_PLAYTEST_SOURCE, "utf-8");
|
|
284142
284152
|
}
|
|
284143
284153
|
function rewriteTsconfig(targetDir, engineRelPath, editorRelPath) {
|
|
284144
284154
|
const tsconfigPath = join15(targetDir, "tsconfig.json");
|
|
@@ -296655,8 +296665,8 @@ function defaultCreateDependencyMode() {
|
|
|
296655
296665
|
return existsSync21(join25(ENGINE_ROOT, "packages", "engine")) ? "link" : "registry";
|
|
296656
296666
|
}
|
|
296657
296667
|
function cliVersion() {
|
|
296658
|
-
if ("0.4.1
|
|
296659
|
-
return "0.4.1
|
|
296668
|
+
if ("0.4.1") {
|
|
296669
|
+
return "0.4.1";
|
|
296660
296670
|
}
|
|
296661
296671
|
try {
|
|
296662
296672
|
const pkg = JSON.parse(readFileSync20(join25(__dirname4, "..", "package.json"), "utf8"));
|
|
@@ -296675,7 +296685,7 @@ function bakedTargetVersions() {
|
|
|
296675
296685
|
if (false)
|
|
296676
296686
|
return void 0;
|
|
296677
296687
|
try {
|
|
296678
|
-
return JSON.parse('{"@vgai/engine":"0.4.1
|
|
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"}');
|
|
296679
296689
|
} catch {
|
|
296680
296690
|
return void 0;
|
|
296681
296691
|
}
|
|
@@ -296765,7 +296775,7 @@ Project:
|
|
|
296765
296775
|
run <name> Run a Node-hosted project capability with validated JSON input
|
|
296766
296776
|
--describe Print the selected capability's schemas and metadata without running
|
|
296767
296777
|
--input <file|-> Read input JSON from a file or stdin (default: {})
|
|
296768
|
-
--yes Confirm write/destructive
|
|
296778
|
+
--yes Confirm write/destructive tool execution
|
|
296769
296779
|
--json Print the full machine-readable catalog/outcome
|
|
296770
296780
|
upgrade [folder] Report + re-sync + re-pin against this engine checkout (default: cwd)
|
|
296771
296781
|
--report Report only \u2014 never write to disk
|
|
@@ -296938,7 +296948,7 @@ Display:
|
|
|
296938
296948
|
grid <on|off> Set grid visibility
|
|
296939
296949
|
helpers <on|off> Set helpers visibility
|
|
296940
296950
|
stats <on|off> Set stats overlay
|
|
296941
|
-
shading <mode> Set shading: solid, wireframe,
|
|
296951
|
+
shading <mode> Set active viewport shading: solid, unlit, wireframe, normals, overdraw
|
|
296942
296952
|
|
|
296943
296953
|
State:
|
|
296944
296954
|
status Print full editor state
|
|
@@ -298603,12 +298613,12 @@ async function run() {
|
|
|
298603
298613
|
console.error(usage);
|
|
298604
298614
|
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
298605
298615
|
}
|
|
298606
|
-
const catalog = await getClient().
|
|
298616
|
+
const catalog = await getClient().listProjectTools();
|
|
298607
298617
|
if (runArgs.includes("--json")) {
|
|
298608
298618
|
console.log(JSON.stringify(catalog, null, 2));
|
|
298609
298619
|
break;
|
|
298610
298620
|
}
|
|
298611
|
-
for (const operation of catalog.
|
|
298621
|
+
for (const operation of catalog.tools) {
|
|
298612
298622
|
console.log(
|
|
298613
298623
|
`${operation.name} ${operation.host} ${operation.permission.risk} ${operation.summary}`
|
|
298614
298624
|
);
|
|
@@ -298616,8 +298626,8 @@ async function run() {
|
|
|
298616
298626
|
for (const error48 of catalog.loadErrors) {
|
|
298617
298627
|
console.error(`\u2717 ${error48.sourcePath}: ${error48.message}`);
|
|
298618
298628
|
}
|
|
298619
|
-
if (catalog.
|
|
298620
|
-
console.log("No project
|
|
298629
|
+
if (catalog.tools.length === 0 && catalog.loadErrors.length === 0) {
|
|
298630
|
+
console.log("No project tools found.");
|
|
298621
298631
|
}
|
|
298622
298632
|
break;
|
|
298623
298633
|
}
|
|
@@ -298630,8 +298640,8 @@ async function run() {
|
|
|
298630
298640
|
console.error(usage);
|
|
298631
298641
|
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
298632
298642
|
}
|
|
298633
|
-
const catalog = await getClient().
|
|
298634
|
-
const operation = catalog.
|
|
298643
|
+
const catalog = await getClient().listProjectTools();
|
|
298644
|
+
const operation = catalog.tools.find((entry) => entry.name === name);
|
|
298635
298645
|
if (!operation) {
|
|
298636
298646
|
console.error(`No project capability is named ${JSON.stringify(name)}.`);
|
|
298637
298647
|
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
@@ -298666,12 +298676,12 @@ ${JSON.stringify(operation.resultSchema, null, 2)}`);
|
|
|
298666
298676
|
);
|
|
298667
298677
|
} catch (error48) {
|
|
298668
298678
|
console.error(
|
|
298669
|
-
`Invalid
|
|
298679
|
+
`Invalid tool input JSON: ${error48 instanceof Error ? error48.message : error48}`
|
|
298670
298680
|
);
|
|
298671
298681
|
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
298672
298682
|
}
|
|
298673
298683
|
}
|
|
298674
|
-
const outcome = await getClient().
|
|
298684
|
+
const outcome = await getClient().runProjectTool(name, input, {
|
|
298675
298685
|
confirm: runArgs.includes("--yes")
|
|
298676
298686
|
});
|
|
298677
298687
|
console.log(JSON.stringify(outcome, null, 2));
|
|
@@ -299423,11 +299433,11 @@ Choose exactly one target: project, --port, or --all.`);
|
|
|
299423
299433
|
break;
|
|
299424
299434
|
case "shading":
|
|
299425
299435
|
if (hasHelpFlag(args)) {
|
|
299426
|
-
console.log("Usage: vgai shading <solid|wireframe|
|
|
299436
|
+
console.log("Usage: vgai shading <solid|unlit|wireframe|normals|overdraw>");
|
|
299427
299437
|
break;
|
|
299428
299438
|
}
|
|
299429
|
-
if (!args[1]) {
|
|
299430
|
-
console.error("Usage: vgai shading <solid|wireframe|
|
|
299439
|
+
if (!["solid", "unlit", "wireframe", "normals", "overdraw"].includes(args[1] ?? "")) {
|
|
299440
|
+
console.error("Usage: vgai shading <solid|unlit|wireframe|normals|overdraw>");
|
|
299431
299441
|
process.exit(1);
|
|
299432
299442
|
}
|
|
299433
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.1
|
|
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.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
|
|
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",
|