@vgai/engine 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/dist/adapter/adapter-module.d.ts +28 -29
- package/dist/adapter/adapter-module.d.ts.map +1 -1
- package/dist/adapter/adapter-module.js +11 -34
- package/dist/adapter/authoring-seam-contract.d.ts +5 -0
- package/dist/adapter/authoring-seam-contract.d.ts.map +1 -1
- package/dist/adapter/authoring-seam-contract.js +1 -0
- package/dist/adapter/authoring.d.ts +16 -0
- package/dist/adapter/authoring.d.ts.map +1 -1
- package/dist/adapter/finders/finder-result.d.ts +2 -2
- package/dist/adapter/finders/finder-result.d.ts.map +1 -1
- package/dist/adapter/finders/index.d.ts +15 -2
- package/dist/adapter/finders/index.d.ts.map +1 -1
- package/dist/adapter/finders/index.js +38 -10
- package/dist/adapter/finders/prefabs-from-stories.d.ts.map +1 -1
- package/dist/adapter/finders/registry.d.ts +45 -0
- package/dist/adapter/finders/registry.d.ts.map +1 -0
- package/dist/adapter/finders/registry.js +56 -0
- package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
- package/dist/adapter/ingest/scene-capture.js +50 -20
- package/dist/adapter/system-adapter.d.ts +3 -1
- package/dist/adapter/system-adapter.d.ts.map +1 -1
- package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -1
- package/dist/canvas-react/pixi-react-root-factory.js +21 -11
- package/dist/data/vite-plugin-data.d.ts +1 -1
- package/dist/data/vite-plugin-data.d.ts.map +1 -1
- package/dist/data/vite-plugin-data.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/input/host-pointer.d.ts +18 -0
- package/dist/input/host-pointer.d.ts.map +1 -1
- package/dist/input/host-pointer.js +54 -5
- package/dist/input/input-manager.d.ts +83 -1
- package/dist/input/input-manager.d.ts.map +1 -1
- package/dist/input/input-manager.js +357 -8
- package/dist/manifest/configuration-kinds.d.ts +97 -0
- package/dist/manifest/configuration-kinds.d.ts.map +1 -0
- package/dist/manifest/configuration-kinds.js +148 -0
- package/dist/manifest/index.d.ts +2 -1
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest/index.js +4 -3
- package/dist/manifest/kind-modules.d.ts +18 -0
- package/dist/manifest/kind-modules.d.ts.map +1 -0
- package/dist/manifest/kind-modules.js +58 -0
- package/dist/manifest/load-file.d.ts +3 -3
- package/dist/manifest/load-file.d.ts.map +1 -1
- package/dist/manifest/load-file.js +4 -4
- package/dist/manifest/load.d.ts +17 -12
- package/dist/manifest/load.d.ts.map +1 -1
- package/dist/manifest/load.js +29 -19
- package/dist/manifest/runtime-environment.d.ts +11 -0
- package/dist/manifest/runtime-environment.d.ts.map +1 -0
- package/dist/manifest/runtime-environment.js +44 -0
- package/dist/manifest/schema.d.ts +10 -9
- package/dist/manifest/schema.d.ts.map +1 -1
- package/dist/manifest/schema.js +32 -27
- package/dist/react/use-data.d.ts +1 -1
- package/dist/react/use-data.js +1 -1
- package/dist/render/matcap-texture.d.ts +5 -0
- package/dist/render/matcap-texture.d.ts.map +1 -0
- package/dist/render/matcap-texture.js +82 -0
- package/dist/render/soft-particle-depth.d.ts +14 -8
- package/dist/render/soft-particle-depth.d.ts.map +1 -1
- package/dist/render/soft-particle-depth.js +37 -14
- package/dist/render/viewport-shading.d.ts +11 -1
- package/dist/render/viewport-shading.d.ts.map +1 -1
- package/dist/render/viewport-shading.js +25 -0
- package/dist/runtime/create-runtime.js +6 -5
- package/dist/runtime/mount-manifest.d.ts.map +1 -1
- package/dist/runtime/mount-manifest.js +11 -2
- package/dist/settings/schema.d.ts +99 -0
- package/dist/settings/schema.d.ts.map +1 -0
- package/dist/settings/schema.js +110 -0
- package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
- package/dist/world3d-react/r3f-root-factory.js +34 -36
- package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
- package/dist/world3d-react/rapier-physics-bridge.js +21 -6
- package/dist-config/config.js +1 -1
- package/dist-config/config.js.map +2 -2
- package/package.json +2 -1
- package/schemas/engine-capabilities.json +4 -4
- package/schemas/vgai-project.schema.json +41 -36
- package/schemas/vgai-settings.schema.json +112 -0
- package/src/adapter/adapter-module.ts +33 -51
- package/src/adapter/authoring-seam-contract.ts +1 -0
- package/src/adapter/authoring.ts +16 -0
- package/src/adapter/finders/finder-result.ts +2 -2
- package/src/adapter/finders/index.ts +68 -12
- package/src/adapter/finders/prefabs-from-stories.ts +2 -2
- package/src/adapter/finders/registry.ts +95 -0
- package/src/adapter/finders/scenes-from-entrypoint-selection.ts +4 -4
- package/src/adapter/ingest/scene-capture.ts +48 -19
- package/src/adapter/system-adapter.ts +3 -1
- package/src/canvas-react/pixi-react-root-factory.tsx +21 -11
- package/src/data/vite-plugin-data.ts +4 -2
- package/src/index.ts +1 -1
- package/src/input/host-pointer.ts +84 -5
- package/src/input/input-manager.ts +404 -7
- package/src/manifest/configuration-kinds.ts +241 -0
- package/src/manifest/index.ts +4 -3
- package/src/manifest/kind-modules.ts +58 -0
- package/src/manifest/load-file.ts +11 -5
- package/src/manifest/load.ts +53 -22
- package/src/manifest/runtime-environment.ts +48 -0
- package/src/manifest/schema.ts +39 -33
- package/src/react/use-data.ts +1 -1
- package/src/render/matcap-texture.ts +92 -0
- package/src/render/soft-particle-depth.ts +43 -14
- package/src/render/viewport-shading.ts +33 -1
- package/src/runtime/create-runtime.ts +6 -5
- package/src/runtime/mount-manifest.ts +13 -2
- package/src/settings/schema.ts +127 -0
- package/src/world3d-react/r3f-root-factory.tsx +45 -39
- package/src/world3d-react/rapier-physics-bridge.tsx +22 -8
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE RUN-CONFIGURATION KIND REGISTRY — the open set of kinds a manifest's
|
|
3
|
+
* `configurations[]` may declare (ARCHITECTURE-CORE §The project model). A run
|
|
4
|
+
* configuration is one of the project's ENTRYPOINTS: something the editor,
|
|
5
|
+
* the CLI or a harness can start by id. The engine registers two kinds
|
|
6
|
+
* here; a capability registers more through the same door; the manifest
|
|
7
|
+
* validates each declaration against its kind's own schema at load, and an
|
|
8
|
+
* unregistered kind refuses loudly naming the registered ones.
|
|
9
|
+
*
|
|
10
|
+
* The implicit configuration every project with roots has is `play` — mount
|
|
11
|
+
* every root in the host — which is never declared and may be named by a
|
|
12
|
+
* `compound`.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
const CONFIGURATION_ROLES = ['run', 'build'];
|
|
16
|
+
/** Register a contribution's kind after checking its shape by name. */
|
|
17
|
+
export function registerContributedConfigurationKind(value, source) {
|
|
18
|
+
const record = (value ?? {});
|
|
19
|
+
const problems = [];
|
|
20
|
+
if (typeof record.kind !== 'string' || record.kind.length === 0)
|
|
21
|
+
problems.push('`kind` must be a non-empty string');
|
|
22
|
+
if (!CONFIGURATION_ROLES.includes(record.role))
|
|
23
|
+
problems.push("`role` must be 'run' or 'build'");
|
|
24
|
+
if (typeof record.describe !== 'string')
|
|
25
|
+
problems.push('`describe` must be a string');
|
|
26
|
+
const schema = record.schema;
|
|
27
|
+
if (!schema || typeof schema.safeParse !== 'function')
|
|
28
|
+
problems.push('`schema` must be a Zod schema');
|
|
29
|
+
const build = record.build;
|
|
30
|
+
if (build !== undefined &&
|
|
31
|
+
(typeof build.tool !== 'string' || typeof build.input !== 'function')) {
|
|
32
|
+
problems.push('`build` must be `{ tool: string; input(configuration) }`');
|
|
33
|
+
}
|
|
34
|
+
if (problems.length > 0) {
|
|
35
|
+
throw new Error(`${source}: not a configuration kind — ${problems.join('; ')}`);
|
|
36
|
+
}
|
|
37
|
+
return registerConfigurationKind(record);
|
|
38
|
+
}
|
|
39
|
+
const registry = new Map();
|
|
40
|
+
/** Register a kind. A second registration replaces the first (a module
|
|
41
|
+
* re-evaluated on save); never throws. */
|
|
42
|
+
export function registerConfigurationKind(registration) {
|
|
43
|
+
const entry = registration;
|
|
44
|
+
registry.set(registration.kind, entry);
|
|
45
|
+
return () => {
|
|
46
|
+
if (registry.get(registration.kind) === entry)
|
|
47
|
+
registry.delete(registration.kind);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export function registeredConfigurationKinds() {
|
|
51
|
+
return [...registry.keys()];
|
|
52
|
+
}
|
|
53
|
+
export function configurationKind(kind) {
|
|
54
|
+
return registry.get(kind);
|
|
55
|
+
}
|
|
56
|
+
/** The id of the implicit configuration: mount every root in the host. */
|
|
57
|
+
export const PLAY_CONFIGURATION_ID = 'play';
|
|
58
|
+
registerConfigurationKind({
|
|
59
|
+
kind: 'process',
|
|
60
|
+
role: 'run',
|
|
61
|
+
describe: 'A process beside the host: an entry module, a port, readiness',
|
|
62
|
+
schema: z
|
|
63
|
+
.object({
|
|
64
|
+
id: z.string().min(1).describe('Configuration id'),
|
|
65
|
+
kind: z.literal('process'),
|
|
66
|
+
entry: z.string().min(1).describe('Project-relative entry module'),
|
|
67
|
+
command: z
|
|
68
|
+
.string()
|
|
69
|
+
.min(1)
|
|
70
|
+
.optional()
|
|
71
|
+
.describe('Shell command that starts it; `npx tsx <entry>` when omitted'),
|
|
72
|
+
port: z.number().int().min(1).max(65535).optional().describe('Port it listens on'),
|
|
73
|
+
cwd: z.string().min(1).optional().describe('Project-relative working directory'),
|
|
74
|
+
env: z.record(z.string(), z.string()).optional().describe('Environment for the process'),
|
|
75
|
+
ready: z
|
|
76
|
+
.object({ http: z.string().min(1).optional().describe('HTTP path answering 2xx when up') })
|
|
77
|
+
.strict()
|
|
78
|
+
.optional()
|
|
79
|
+
.describe('Readiness beyond the port accepting connections'),
|
|
80
|
+
})
|
|
81
|
+
.strict(),
|
|
82
|
+
});
|
|
83
|
+
registerConfigurationKind({
|
|
84
|
+
kind: 'compound',
|
|
85
|
+
role: 'run',
|
|
86
|
+
describe: 'Several configurations started together; `play` names the host mount',
|
|
87
|
+
schema: z
|
|
88
|
+
.object({
|
|
89
|
+
id: z.string().min(1).describe('Configuration id'),
|
|
90
|
+
kind: z.literal('compound'),
|
|
91
|
+
run: z.array(z.string().min(1)).min(1).describe('Configuration ids, `play` included'),
|
|
92
|
+
instances: z
|
|
93
|
+
.number()
|
|
94
|
+
.int()
|
|
95
|
+
.min(1)
|
|
96
|
+
.optional()
|
|
97
|
+
.describe('Instances of the host mount to run against the rest'),
|
|
98
|
+
})
|
|
99
|
+
.strict(),
|
|
100
|
+
});
|
|
101
|
+
registerConfigurationKind({
|
|
102
|
+
kind: 'bundle',
|
|
103
|
+
role: 'build',
|
|
104
|
+
describe: "The project's web bundle: its build script, then dist/ packaged as the artifact",
|
|
105
|
+
schema: z
|
|
106
|
+
.object({
|
|
107
|
+
id: z.string().min(1).describe('Configuration id'),
|
|
108
|
+
kind: z.literal('bundle'),
|
|
109
|
+
script: z.string().min(1).optional().describe('package.json script that builds (`build`)'),
|
|
110
|
+
args: z.array(z.string()).optional().describe('Arguments passed after `--`'),
|
|
111
|
+
})
|
|
112
|
+
.strict(),
|
|
113
|
+
});
|
|
114
|
+
/** Validate `configurations[]` against the registry: every kind registered, every
|
|
115
|
+
* declaration its kind's shape, ids unique, compound members declared. */
|
|
116
|
+
export function configurationIssues(configurations) {
|
|
117
|
+
const issues = [];
|
|
118
|
+
const ids = new Set();
|
|
119
|
+
for (const declaration of configurations) {
|
|
120
|
+
if (ids.has(declaration.id))
|
|
121
|
+
issues.push(`configurations: duplicate id "${declaration.id}"`);
|
|
122
|
+
ids.add(declaration.id);
|
|
123
|
+
const registration = registry.get(declaration.kind);
|
|
124
|
+
if (!registration) {
|
|
125
|
+
issues.push(`configurations "${declaration.id}": unknown kind "${declaration.kind}" — registered: ${registeredConfigurationKinds()
|
|
126
|
+
.map((k) => `"${k}"`)
|
|
127
|
+
.join(', ')}`);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const parsed = registration.schema.safeParse(declaration);
|
|
131
|
+
if (!parsed.success) {
|
|
132
|
+
for (const issue of parsed.error.issues) {
|
|
133
|
+
issues.push(`configurations "${declaration.id}" (${declaration.kind}): ${issue.path.join('.') || '(declaration)'}: ${issue.message}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
for (const declaration of configurations) {
|
|
138
|
+
if (declaration.kind !== 'compound')
|
|
139
|
+
continue;
|
|
140
|
+
const members = declaration.run ?? [];
|
|
141
|
+
for (const member of members) {
|
|
142
|
+
if (member !== PLAY_CONFIGURATION_ID && !ids.has(member)) {
|
|
143
|
+
issues.push(`configurations "${declaration.id}": member "${member}" is not a declared configuration (or "${PLAY_CONFIGURATION_ID}")`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return issues;
|
|
148
|
+
}
|
package/dist/manifest/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
export * from './configuration-kinds';
|
|
1
2
|
export { isManifestFilename, MANIFEST_FILENAME, REMOVED_MANIFEST_FILENAME, removedManifestFilenameMessage, } from './filename';
|
|
2
3
|
export type { ResolvedAdapter, ResolvedAdapterRoot, ResolvedGameManifest } from './load';
|
|
3
|
-
export {
|
|
4
|
+
export { loadGameManifest } from './load';
|
|
4
5
|
export type { AdapterRoot, GameManifest, RootAdapter } from './schema';
|
|
5
6
|
export { AdapterRootSchema, GameManifestSchema, RootAdapterSchema } from './schema';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AACzF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAGA,cAAc,uBAAuB,CAAC;AACtC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAC1C,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/manifest/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Game manifest (vgai.project.json) — schema + loader (T3.1 slice
|
|
2
2
|
// 1)..
|
|
3
|
+
export * from './configuration-kinds';
|
|
3
4
|
export { isManifestFilename, MANIFEST_FILENAME, REMOVED_MANIFEST_FILENAME, removedManifestFilenameMessage, } from './filename';
|
|
4
|
-
export {
|
|
5
|
+
export { loadGameManifest } from './load';
|
|
5
6
|
export { AdapterRootSchema, GameManifestSchema, RootAdapterSchema } from './schema';
|
|
6
|
-
//
|
|
7
|
+
// File loading and kind-module discovery read `node:fs` and are
|
|
7
8
|
// deliberately NOT re-exported here — this barrel must stay import-safe for
|
|
8
9
|
// browser bundles. Import it directly from `@engine/manifest/load-file` in
|
|
9
|
-
// Node-only contexts
|
|
10
|
+
// Node-only contexts; kind discovery lives in `@engine/manifest/kind-modules`.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a project's CONFIGURATION-KIND CONTRIBUTIONS live and how a host
|
|
3
|
+
* takes them in (ARCHITECTURE-CORE §The project model). A module named
|
|
4
|
+
* `src/contributions/<name>.kind.ts` (or `.tsx`) exports `kind`, a plain
|
|
5
|
+
* `ConfigurationKindContribution`; the HOST that loads the manifest — the
|
|
6
|
+
* editor server through Vite's SSR loader, a project's own validate script
|
|
7
|
+
* through tsx — imports each and registers it in its own registry through
|
|
8
|
+
* {@link registerContributedConfigurationKind}. Node-only: it walks the
|
|
9
|
+
* project folder.
|
|
10
|
+
*/
|
|
11
|
+
/** Whether one file name is a kind contribution by the convention. */
|
|
12
|
+
export declare function isConfigurationKindModule(fileName: string): boolean;
|
|
13
|
+
/** Absolute paths of the project's kind contributions, sorted. */
|
|
14
|
+
export declare function contributedKindModulePaths(projectDir: string): string[];
|
|
15
|
+
/** Register the `kind` export of an already-imported module; the source
|
|
16
|
+
* path names the module in a refusal. */
|
|
17
|
+
export declare function registerKindModule(module: unknown, source: string): () => void;
|
|
18
|
+
//# sourceMappingURL=kind-modules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kind-modules.d.ts","sourceRoot":"","sources":["../../src/manifest/kind-modules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,sEAAsE;AACtE,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,kEAAkE;AAClE,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBvE;AAED;0CAC0C;AAC1C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,CAM9E"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a project's CONFIGURATION-KIND CONTRIBUTIONS live and how a host
|
|
3
|
+
* takes them in (ARCHITECTURE-CORE §The project model). A module named
|
|
4
|
+
* `src/contributions/<name>.kind.ts` (or `.tsx`) exports `kind`, a plain
|
|
5
|
+
* `ConfigurationKindContribution`; the HOST that loads the manifest — the
|
|
6
|
+
* editor server through Vite's SSR loader, a project's own validate script
|
|
7
|
+
* through tsx — imports each and registers it in its own registry through
|
|
8
|
+
* {@link registerContributedConfigurationKind}. Node-only: it walks the
|
|
9
|
+
* project folder.
|
|
10
|
+
*/
|
|
11
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { registerContributedConfigurationKind } from './configuration-kinds';
|
|
14
|
+
const KIND_SUFFIXES = ['.kind.ts', '.kind.tsx'];
|
|
15
|
+
/** Whether one file name is a kind contribution by the convention. */
|
|
16
|
+
export function isConfigurationKindModule(fileName) {
|
|
17
|
+
return KIND_SUFFIXES.some((suffix) => fileName.endsWith(suffix));
|
|
18
|
+
}
|
|
19
|
+
/** Absolute paths of the project's kind contributions, sorted. */
|
|
20
|
+
export function contributedKindModulePaths(projectDir) {
|
|
21
|
+
const found = [];
|
|
22
|
+
const walk = (directory) => {
|
|
23
|
+
let names;
|
|
24
|
+
try {
|
|
25
|
+
names = readdirSync(directory);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (const name of names) {
|
|
31
|
+
if (name.startsWith('.') || name === 'node_modules')
|
|
32
|
+
continue;
|
|
33
|
+
const absolute = join(directory, name);
|
|
34
|
+
let isDirectory = false;
|
|
35
|
+
try {
|
|
36
|
+
isDirectory = statSync(absolute).isDirectory();
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (isDirectory)
|
|
42
|
+
walk(absolute);
|
|
43
|
+
else if (isConfigurationKindModule(name))
|
|
44
|
+
found.push(absolute);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
walk(join(projectDir, 'src', 'contributions'));
|
|
48
|
+
return found.sort();
|
|
49
|
+
}
|
|
50
|
+
/** Register the `kind` export of an already-imported module; the source
|
|
51
|
+
* path names the module in a refusal. */
|
|
52
|
+
export function registerKindModule(module, source) {
|
|
53
|
+
const exported = module?.kind;
|
|
54
|
+
if (exported === undefined) {
|
|
55
|
+
throw new Error(`${source}: a kind contribution must export \`kind\``);
|
|
56
|
+
}
|
|
57
|
+
return registerContributedConfigurationKind(exported, source);
|
|
58
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type ResolvedGameManifest } from './load';
|
|
1
|
+
import { type LoadGameManifestOptions, type ResolvedGameManifest } from './load';
|
|
2
2
|
export { hasManifest, manifestWritePath, resolveManifestPath } from './locate';
|
|
3
3
|
/** Read + JSON.parse `path`, then resolve it via `loadGameManifest`. Node-only. */
|
|
4
|
-
export declare function loadGameManifestFile(path: string): ResolvedGameManifest;
|
|
4
|
+
export declare function loadGameManifestFile(path: string, options?: LoadGameManifestOptions): ResolvedGameManifest;
|
|
5
5
|
/** {@link loadGameManifestFile} against `dir`'s `vgai.project.json`. */
|
|
6
|
-
export declare function loadGameManifestDir(dir: string): ResolvedGameManifest;
|
|
6
|
+
export declare function loadGameManifestDir(dir: string, options?: LoadGameManifestOptions): ResolvedGameManifest;
|
|
7
7
|
//# sourceMappingURL=load-file.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-file.d.ts","sourceRoot":"","sources":["../../src/manifest/load-file.ts"],"names":[],"mappings":"AASA,OAAO,EAAoB,KAAK,oBAAoB,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"load-file.d.ts","sourceRoot":"","sources":["../../src/manifest/load-file.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,uBAAuB,EAAoB,KAAK,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAMnG,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/E,mFAAmF;AACnF,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,uBAA4B,GACpC,oBAAoB,CAGtB;AAED,wEAAwE;AACxE,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,uBAA4B,GACpC,oBAAoB,CAEtB"}
|
|
@@ -13,11 +13,11 @@ import { resolveManifestPath } from './locate';
|
|
|
13
13
|
// module.
|
|
14
14
|
export { hasManifest, manifestWritePath, resolveManifestPath } from './locate';
|
|
15
15
|
/** Read + JSON.parse `path`, then resolve it via `loadGameManifest`. Node-only. */
|
|
16
|
-
export function loadGameManifestFile(path) {
|
|
16
|
+
export function loadGameManifestFile(path, options = {}) {
|
|
17
17
|
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
18
|
-
return loadGameManifest(raw);
|
|
18
|
+
return loadGameManifest(raw, options);
|
|
19
19
|
}
|
|
20
20
|
/** {@link loadGameManifestFile} against `dir`'s `vgai.project.json`. */
|
|
21
|
-
export function loadGameManifestDir(dir) {
|
|
22
|
-
return loadGameManifestFile(resolveManifestPath(dir));
|
|
21
|
+
export function loadGameManifestDir(dir, options = {}) {
|
|
22
|
+
return loadGameManifestFile(resolveManifestPath(dir), options);
|
|
23
23
|
}
|
package/dist/manifest/load.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type DeclaredConfiguration } from './configuration-kinds';
|
|
2
|
+
import { type GameManifest, type LearnMetadata } from './schema';
|
|
2
3
|
/** D6's resolved adapter identities. */
|
|
3
4
|
export type ResolvedAdapter = {
|
|
4
5
|
readonly type: 'builtin';
|
|
@@ -62,14 +63,15 @@ export interface ResolvedGameManifest {
|
|
|
62
63
|
};
|
|
63
64
|
/** Sorted by zOrder; ties broken by original array order (§3). */
|
|
64
65
|
readonly roots: readonly ResolvedAdapterRoot[];
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
/** The declared run configurations, validated by kind (`run-kinds.ts`). */
|
|
67
|
+
readonly configurations: readonly DeclaredConfiguration[];
|
|
68
|
+
/** Ids whose kind no registry here knows — only ever non-empty when the
|
|
69
|
+
* caller loaded with `configurationKinds: 'defer'` (a bundled host that
|
|
70
|
+
* cannot evaluate a project's kind contributions); the editor session
|
|
71
|
+
* is the validator for those. */
|
|
72
|
+
readonly deferredConfigurationKinds: readonly string[];
|
|
73
|
+
/** Deploy-baked relay credentials, when the served manifest carries them. */
|
|
74
|
+
readonly relay: GameManifest['relay'];
|
|
73
75
|
readonly resolution: {
|
|
74
76
|
readonly width: number;
|
|
75
77
|
readonly height: number;
|
|
@@ -117,13 +119,16 @@ export interface ResolvedGameManifest {
|
|
|
117
119
|
* gallery/wizard/Learn-catalog registries. */
|
|
118
120
|
readonly learn: LearnMetadata | undefined;
|
|
119
121
|
}
|
|
120
|
-
/** Default relative path for `server.module` when omitted (§3) — the scaffolded Colyseus bootstrap. */
|
|
121
|
-
export declare const DEFAULT_SERVER_MODULE = "server/colyseus-setup.ts";
|
|
122
122
|
/**
|
|
123
123
|
* Parse + validate + resolve a raw manifest value into a `ResolvedGameManifest`.
|
|
124
124
|
* Pure data-in/data-out (no `fs`) — see `load-file.ts` for the Node path-based
|
|
125
125
|
* wrapper. Throws a descriptive `Error` (naming the offending root/field) on
|
|
126
126
|
* any Zod validation failure or cross-field rule violation.
|
|
127
127
|
*/
|
|
128
|
-
export
|
|
128
|
+
export interface LoadGameManifestOptions {
|
|
129
|
+
/** `require` (default): a declaration of an unregistered kind refuses.
|
|
130
|
+
* `defer`: it is reported in `deferredConfigurationKinds` instead. */
|
|
131
|
+
readonly configurationKinds?: 'require' | 'defer';
|
|
132
|
+
}
|
|
133
|
+
export declare function loadGameManifest(raw: unknown, options?: LoadGameManifestOptions): ResolvedGameManifest;
|
|
129
134
|
//# sourceMappingURL=load.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/manifest/load.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/manifest/load.ts"],"names":[],"mappings":"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"}
|
package/dist/manifest/load.js
CHANGED
|
@@ -12,9 +12,8 @@
|
|
|
12
12
|
// No `fs` import here on purpose — `load-file.ts` is the thin Node-only
|
|
13
13
|
// wrapper that reads a path and calls this function, so browser bundles that
|
|
14
14
|
// only need `loadGameManifest` never pull in `node:fs`.
|
|
15
|
+
import { configurationIssues, configurationKind, } from './configuration-kinds';
|
|
15
16
|
import { GameManifestSchema, } from './schema';
|
|
16
|
-
/** Default relative path for `server.module` when omitted (§3) — the scaffolded Colyseus bootstrap. */
|
|
17
|
-
export const DEFAULT_SERVER_MODULE = 'server/colyseus-setup.ts';
|
|
18
17
|
const SEMVER_RE = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-.]+)?(?:\+[0-9A-Za-z-.]+)?$/;
|
|
19
18
|
// ---------------------------------------------------------------------------
|
|
20
19
|
// Adapter shape guards
|
|
@@ -119,16 +118,7 @@ function resolveRoot(root) {
|
|
|
119
118
|
loop: root.loop,
|
|
120
119
|
};
|
|
121
120
|
}
|
|
122
|
-
|
|
123
|
-
// Entry point
|
|
124
|
-
// ---------------------------------------------------------------------------
|
|
125
|
-
/**
|
|
126
|
-
* Parse + validate + resolve a raw manifest value into a `ResolvedGameManifest`.
|
|
127
|
-
* Pure data-in/data-out (no `fs`) — see `load-file.ts` for the Node path-based
|
|
128
|
-
* wrapper. Throws a descriptive `Error` (naming the offending root/field) on
|
|
129
|
-
* any Zod validation failure or cross-field rule violation.
|
|
130
|
-
*/
|
|
131
|
-
export function loadGameManifest(raw) {
|
|
121
|
+
export function loadGameManifest(raw, options = {}) {
|
|
132
122
|
// Removed-format guard FIRST, on the raw value: a root declaring a removed
|
|
133
123
|
// content field would otherwise fail Zod's `roots` discriminated union with
|
|
134
124
|
// a confusing shape error instead of the named migration message.
|
|
@@ -156,13 +146,31 @@ export function loadGameManifest(raw) {
|
|
|
156
146
|
}));
|
|
157
147
|
resolvedWithIndex.sort((a, b) => a.root.zOrder - b.root.zOrder || a.index - b.index);
|
|
158
148
|
const roots = resolvedWithIndex.map(({ root }) => root);
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
149
|
+
const configurations = (manifest.configurations ?? []);
|
|
150
|
+
// Kinds are OPEN (ARCHITECTURE-CORE §The project model): each declaration
|
|
151
|
+
// is checked against its registered kind's own schema HERE, where the
|
|
152
|
+
// host's registry is, not in the Zod schema. A host that cannot evaluate a
|
|
153
|
+
// project's kind contributions defers unknown kinds by name instead of
|
|
154
|
+
// refusing them.
|
|
155
|
+
const deferredConfigurationKinds = [];
|
|
156
|
+
const kindIssues = configurationIssues(configurations).filter((issue) => {
|
|
157
|
+
if (options.configurationKinds !== 'defer')
|
|
158
|
+
return true;
|
|
159
|
+
const unknown = /^configurations "([^"]+)": unknown kind/.exec(issue);
|
|
160
|
+
if (!unknown)
|
|
161
|
+
return true;
|
|
162
|
+
deferredConfigurationKinds.push(unknown[1]);
|
|
163
|
+
return false;
|
|
164
|
+
});
|
|
165
|
+
if (kindIssues.length > 0) {
|
|
166
|
+
throw new Error(`Game manifest: ${kindIssues.join('\n ')}`);
|
|
167
|
+
}
|
|
168
|
+
for (const configuration of configurations) {
|
|
169
|
+
if (!configurationKind(configuration.kind) &&
|
|
170
|
+
!deferredConfigurationKinds.includes(configuration.id)) {
|
|
171
|
+
deferredConfigurationKinds.push(configuration.id);
|
|
164
172
|
}
|
|
165
|
-
|
|
173
|
+
}
|
|
166
174
|
return {
|
|
167
175
|
manifestVersion: manifest.manifestVersion,
|
|
168
176
|
name: manifest.name,
|
|
@@ -170,7 +178,9 @@ export function loadGameManifest(raw) {
|
|
|
170
178
|
version: manifest.version,
|
|
171
179
|
engine: { version: manifest.engine.version },
|
|
172
180
|
roots,
|
|
173
|
-
|
|
181
|
+
configurations,
|
|
182
|
+
deferredConfigurationKinds,
|
|
183
|
+
relay: manifest.relay,
|
|
174
184
|
resolution: manifest.resolution,
|
|
175
185
|
rendering: manifest.rendering,
|
|
176
186
|
authoring: manifest.authoring,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** `engines.node` from the project's `package.json`, or `null` when the
|
|
2
|
+
* project declares none (or has no package.json). */
|
|
3
|
+
export declare function declaredNodeRange(projectDir: string): string | null;
|
|
4
|
+
/**
|
|
5
|
+
* Why a process of this project cannot start on the running Node, spelled
|
|
6
|
+
* for the person who will fix it — or `null` when it can. A range that is
|
|
7
|
+
* not valid semver is itself the issue: a declaration nobody can satisfy is
|
|
8
|
+
* named, never skipped.
|
|
9
|
+
*/
|
|
10
|
+
export declare function nodeRuntimeIssue(projectDir: string, running?: string): string | null;
|
|
11
|
+
//# sourceMappingURL=runtime-environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-environment.d.ts","sourceRoot":"","sources":["../../src/manifest/runtime-environment.ts"],"names":[],"mappings":"AAeA;sDACsD;AACtD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQnE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,MAA8B,GACtC,MAAM,GAAG,IAAI,CAWf"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE RUNTIME HALF OF A PROJECT'S ENVIRONMENT (ARCHITECTURE-CORE §The
|
|
3
|
+
* project model, "environment"): the Node version a project's processes need
|
|
4
|
+
* is declared ONCE, where the ecosystem already declares it —
|
|
5
|
+
* `package.json` `engines.node` — and read here by whatever starts a
|
|
6
|
+
* `process` configuration (the editor server's configurations route, the
|
|
7
|
+
* CLI's autoboot). The manifest carries no `environment` key: a second
|
|
8
|
+
* declaration of the same fact is the drift a single home prevents.
|
|
9
|
+
*
|
|
10
|
+
* Node-only (reads the project folder), like `locate.ts`.
|
|
11
|
+
*/
|
|
12
|
+
import { readFileSync } from 'node:fs';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import semver from 'semver';
|
|
15
|
+
/** `engines.node` from the project's `package.json`, or `null` when the
|
|
16
|
+
* project declares none (or has no package.json). */
|
|
17
|
+
export function declaredNodeRange(projectDir) {
|
|
18
|
+
try {
|
|
19
|
+
const raw = JSON.parse(readFileSync(join(projectDir, 'package.json'), 'utf-8'));
|
|
20
|
+
const engines = raw?.engines;
|
|
21
|
+
return typeof engines?.node === 'string' && engines.node.trim() ? engines.node.trim() : null;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Why a process of this project cannot start on the running Node, spelled
|
|
29
|
+
* for the person who will fix it — or `null` when it can. A range that is
|
|
30
|
+
* not valid semver is itself the issue: a declaration nobody can satisfy is
|
|
31
|
+
* named, never skipped.
|
|
32
|
+
*/
|
|
33
|
+
export function nodeRuntimeIssue(projectDir, running = process.versions.node) {
|
|
34
|
+
const range = declaredNodeRange(projectDir);
|
|
35
|
+
if (range === null)
|
|
36
|
+
return null;
|
|
37
|
+
if (semver.validRange(range) === null) {
|
|
38
|
+
return `package.json declares engines.node "${range}", which is not a semver range`;
|
|
39
|
+
}
|
|
40
|
+
if (semver.satisfies(running, range, { includePrerelease: true }))
|
|
41
|
+
return null;
|
|
42
|
+
return (`package.json declares engines.node "${range}" and this host runs Node ${running} — ` +
|
|
43
|
+
`run the editor and \`vgai\` on a Node that satisfies it, or change engines.node`);
|
|
44
|
+
}
|
|
@@ -168,15 +168,16 @@ export declare const GameManifestSchema: z.ZodObject<{
|
|
|
168
168
|
}, z.core.$strict>>>;
|
|
169
169
|
}, z.core.$strict>>;
|
|
170
170
|
}, z.core.$strict>>;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
171
|
+
configurations: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
172
|
+
id: z.ZodString;
|
|
173
|
+
kind: z.ZodString;
|
|
174
|
+
}, z.core.$loose>>>;
|
|
175
|
+
relay: z.ZodOptional<z.ZodObject<{
|
|
176
|
+
signalingUrl: z.ZodOptional<z.ZodString>;
|
|
177
|
+
grant: z.ZodOptional<z.ZodString>;
|
|
178
|
+
sessionUrl: z.ZodOptional<z.ZodString>;
|
|
179
|
+
accessToken: z.ZodOptional<z.ZodString>;
|
|
180
|
+
expiresAt: z.ZodOptional<z.ZodNumber>;
|
|
180
181
|
}, z.core.$strict>>;
|
|
181
182
|
resolution: z.ZodOptional<z.ZodObject<{
|
|
182
183
|
width: z.ZodNumber;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/manifest/schema.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAG,CAAU,CAAC;AAsFhD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;qBA0H3B,CAAC;AACJ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAM5D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqFnB,CAAC;AACZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAkB5D,eAAO,MAAM,eAAe;;;;;EAMzB,CAAC;AACJ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,qBAAqB;;;;EAEa,CAAC;AAChD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;kBAqC7B,CAAC;AACJ,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/manifest/schema.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAG,CAAU,CAAC;AAsFhD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;qBA0H3B,CAAC;AACJ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAM5D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqFnB,CAAC;AACZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAkB5D,eAAO,MAAM,eAAe;;;;;EAMzB,CAAC;AACJ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,qBAAqB;;;;EAEa,CAAC;AAChD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;kBAqC7B,CAAC;AACJ,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAchE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA4TyD,CAAC;AAEzF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
|
package/dist/manifest/schema.js
CHANGED
|
@@ -328,6 +328,13 @@ export const LearnMetadataSchema = z
|
|
|
328
328
|
// ---------------------------------------------------------------------------
|
|
329
329
|
// Game manifest (vgai.project.json)
|
|
330
330
|
// ---------------------------------------------------------------------------
|
|
331
|
+
/** The envelope of one run configuration; the kind's schema takes the rest. */
|
|
332
|
+
const ConfigurationEnvelopeSchema = z
|
|
333
|
+
.object({
|
|
334
|
+
id: z.string().min(1).describe('Configuration id, unique in the manifest'),
|
|
335
|
+
kind: z.string().min(1).describe('A registered run kind'),
|
|
336
|
+
})
|
|
337
|
+
.passthrough();
|
|
331
338
|
export const GameManifestSchema = z
|
|
332
339
|
.object({
|
|
333
340
|
$schema: z
|
|
@@ -354,7 +361,6 @@ export const GameManifestSchema = z
|
|
|
354
361
|
.describe('Engine version pin'),
|
|
355
362
|
roots: z
|
|
356
363
|
.array(AdapterRootSchema)
|
|
357
|
-
.min(1)
|
|
358
364
|
.superRefine((roots, ctx) => {
|
|
359
365
|
// D-V6 (debt): root ids are described as unique above but that was
|
|
360
366
|
// describe-only at the SCHEMA level — only load.ts's loader-level
|
|
@@ -410,7 +416,7 @@ export const GameManifestSchema = z
|
|
|
410
416
|
});
|
|
411
417
|
}
|
|
412
418
|
})
|
|
413
|
-
.describe("The
|
|
419
|
+
.describe("The project's explicit adapter-root composition — ZERO OR MORE roots, and no implicit root: a project with no roots mounts nothing (a library of models, a folder of documents) and the editor derives its chrome from what IS declared. " +
|
|
414
420
|
'Root ids are unique, and a project declares at most ONE world root per medium — ' +
|
|
415
421
|
'one `three`, one `dom`, one canvas-surface root (first-party canvas, canvas ingest ' +
|
|
416
422
|
'and canvas module are the same medium).'),
|
|
@@ -443,40 +449,39 @@ export const GameManifestSchema = z
|
|
|
443
449
|
.strict()
|
|
444
450
|
.optional()
|
|
445
451
|
.describe('Editor-only authoring metadata; never runtime ownership'),
|
|
446
|
-
|
|
452
|
+
configurations: z
|
|
453
|
+
.array(ConfigurationEnvelopeSchema)
|
|
454
|
+
.optional()
|
|
455
|
+
.describe("The project's run configurations — its ENTRYPOINTS beyond the host mount (`play`): each an " +
|
|
456
|
+
'id and a registered kind (`process`, `compound`, and whatever a capability registers) with ' +
|
|
457
|
+
"that kind's own fields. The editor's transport, `vgai run <id>` and a harness start the same declaration."),
|
|
458
|
+
relay: z
|
|
447
459
|
.object({
|
|
448
|
-
|
|
449
|
-
endpoint: z
|
|
460
|
+
signalingUrl: z
|
|
450
461
|
.string()
|
|
451
462
|
.optional()
|
|
452
|
-
.describe('
|
|
453
|
-
|
|
454
|
-
"`server/colyseus-setup.ts` listens on. Stated here because the endpoint is the game's " +
|
|
455
|
-
'own deployment fact, not something the editor may guess'),
|
|
456
|
-
module: z
|
|
463
|
+
.describe('Managed relay signaling URL to prefer over the client default; omitted when the deploy did not pin one'),
|
|
464
|
+
grant: z
|
|
457
465
|
.string()
|
|
458
466
|
.optional()
|
|
459
|
-
.describe('
|
|
460
|
-
|
|
461
|
-
.
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
.number()
|
|
471
|
-
.describe('Token expiry as epoch milliseconds; the client falls back to a tokenless join once elapsed'),
|
|
472
|
-
})
|
|
473
|
-
.strict()
|
|
467
|
+
.describe('Room-scoped managed-relay GRANT minted at `vgai deploy`; players exchange it for a fresh token at `sessionUrl`'),
|
|
468
|
+
sessionUrl: z
|
|
469
|
+
.string()
|
|
470
|
+
.optional()
|
|
471
|
+
.describe('Public session endpoint where a deployed client exchanges the grant for a short-lived relay token'),
|
|
472
|
+
accessToken: z
|
|
473
|
+
.string()
|
|
474
|
+
.optional()
|
|
475
|
+
.describe('A baked relay token (older deploys); used directly while unexpired'),
|
|
476
|
+
expiresAt: z
|
|
477
|
+
.number()
|
|
474
478
|
.optional()
|
|
475
|
-
.describe('
|
|
479
|
+
.describe('Token expiry as epoch milliseconds; the client falls back to a tokenless join once elapsed'),
|
|
476
480
|
})
|
|
477
481
|
.strict()
|
|
478
482
|
.optional()
|
|
479
|
-
.describe('
|
|
483
|
+
.describe('Deploy-baked managed-relay credentials — a DEPLOYMENT fact. NEVER hand-authored in source: written only into ' +
|
|
484
|
+
'the staged manifest by `vgai deploy` and read by the deployed client at connect time.'),
|
|
480
485
|
resolution: z
|
|
481
486
|
.object({
|
|
482
487
|
width: z.number().describe('Canvas width in pixels'),
|