@forgeax/engine-devkit 0.1.4 → 0.1.6
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 +19 -4
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/cli-output.unit.test.d.ts +2 -0
- package/dist/__tests__/cli-output.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gltf-source-key-diagnostics.integration.test.d.ts +2 -0
- package/dist/__tests__/gltf-source-key-diagnostics.integration.test.d.ts.map +1 -0
- package/dist/__tests__/preview-port.integration.test.d.ts +2 -0
- package/dist/__tests__/preview-port.integration.test.d.ts.map +1 -0
- package/dist/__tests__/rhi-debug-build-graph.integration.test.d.ts +2 -0
- package/dist/__tests__/rhi-debug-build-graph.integration.test.d.ts.map +1 -0
- package/dist/__tests__/sdk-update.unit.test.d.ts +2 -0
- package/dist/__tests__/sdk-update.unit.test.d.ts.map +1 -0
- package/dist/assets.d.ts.map +1 -1
- package/dist/bootstrap-commands.d.ts.map +1 -1
- package/dist/cli-output.d.ts +4 -0
- package/dist/cli-output.d.ts.map +1 -0
- package/dist/cli.mjs +380 -567
- package/dist/cli.mjs.map +1 -1
- package/dist/commands.d.ts.map +1 -1
- package/dist/host/__tests__/bootstrap-root-owner.test-d.d.ts +2 -0
- package/dist/host/__tests__/bootstrap-root-owner.test-d.d.ts.map +1 -0
- package/dist/host/project-bootstrap.d.ts +4 -2
- package/dist/host/project-bootstrap.d.ts.map +1 -1
- package/dist/host/resource-bootstrap.d.ts +5 -3
- package/dist/host/resource-bootstrap.d.ts.map +1 -1
- package/dist/host.d.ts +2 -1
- package/dist/host.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +303 -570
- package/dist/index.mjs.map +1 -1
- package/dist/project.d.ts +0 -1
- package/dist/project.d.ts.map +1 -1
- package/dist/rhi-debug/cli-context.d.ts.map +1 -1
- package/dist/sdk-bootstrap.d.ts +9 -0
- package/dist/sdk-bootstrap.d.ts.map +1 -1
- package/dist/sdk-cli.mjs +190 -24
- package/dist/sdk-cli.mjs.map +1 -1
- package/dist/sdk-install.d.ts.map +1 -1
- package/dist/sdk-update.d.ts +23 -0
- package/dist/sdk-update.d.ts.map +1 -0
- package/dist/tools/benchmark/__tests__/benchmark-vocabulary-owner.test-d.d.ts +2 -0
- package/dist/tools/benchmark/__tests__/benchmark-vocabulary-owner.test-d.d.ts.map +1 -0
- package/dist/tools/benchmark/harness.d.ts.map +1 -1
- package/dist/tools/browser-host.d.ts.map +1 -1
- package/dist/tools/native-preview.d.ts.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +29 -30
- package/dist/__tests__/tool-migration.test.d.ts +0 -2
- package/dist/__tests__/tool-migration.test.d.ts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { deflateRawSync } from 'zlib';
|
|
2
2
|
import { createHash } from 'crypto';
|
|
3
|
-
import { readFile, writeFile, copyFile, readdir,
|
|
3
|
+
import { readFile, writeFile, mkdir, copyFile, readdir, mkdtemp, cp, rename, rm, stat, symlink, realpath, unlink, lstat, readlink, rmdir, access } from 'fs/promises';
|
|
4
4
|
import { resolve, relative, sep, isAbsolute, extname, dirname, basename, join } from 'path';
|
|
5
|
-
import { existsSync
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
6
|
import { createRequire } from 'module';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
import { audioImporter } from '@forgeax/engine-audio-webaudio/audio-importer';
|
|
@@ -12,9 +12,9 @@ import { gltfImporter } from '@forgeax/engine-gltf';
|
|
|
12
12
|
import { imageImporter } from '@forgeax/engine-image/image-importer';
|
|
13
13
|
import { BUILTIN_MESH_ASSETS } from '@forgeax/engine-pack/builtin';
|
|
14
14
|
import { scanInventory } from '@forgeax/engine-pack/scanner';
|
|
15
|
-
import { validatePreviewArtifactManifest, createMaterialPreviewContribution, createMeshPreviewContribution, createVfxPreviewContribution, createTexturePreviewContribution,
|
|
15
|
+
import { validatePreviewArtifactManifest, createMaterialPreviewContribution, createMeshPreviewContribution, createVfxPreviewContribution, createTexturePreviewContribution, validateCanonicalKitReceipt, describeResourcePreviewFailure } from '@forgeax/engine-preview';
|
|
16
16
|
import { createMaterialPackCooker } from '@forgeax/engine-shader-compiler';
|
|
17
|
-
import { err, ok
|
|
17
|
+
import { createStandaloneRuntimeAssetBinding, err, ok } from '@forgeax/engine-types';
|
|
18
18
|
import { createParticleCodeNativeCookerFromRoots } from '@forgeax/engine-vfx-compiler';
|
|
19
19
|
import { pluginPack, reloadAssetHost } from '@forgeax/engine-vite-plugin-pack';
|
|
20
20
|
import { forgeaxShader } from '@forgeax/engine-vite-plugin-shader';
|
|
@@ -26,7 +26,9 @@ import { execFile } from 'child_process';
|
|
|
26
26
|
import { tmpdir } from 'os';
|
|
27
27
|
import { promisify } from 'util';
|
|
28
28
|
import { createRhiDebugError, decodeTape, openReplay, buildFrameModel } from '@forgeax/engine-rhi-debug';
|
|
29
|
-
import {
|
|
29
|
+
import { rhi, createShaderModule } from '@forgeax/engine-rhi-null';
|
|
30
|
+
import { build, preview, createServer as createServer$2 } from 'vite';
|
|
31
|
+
import { createServer as createServer$1 } from 'net';
|
|
30
32
|
import { startVitest } from 'vitest/node';
|
|
31
33
|
import materialPreviewPlugin from '@forgeax/engine-preview/material';
|
|
32
34
|
import meshPreviewPlugin from '@forgeax/engine-preview/mesh';
|
|
@@ -36,9 +38,8 @@ import { validateArtifactManifest, defineTool, createToolRuntime, validateRealmB
|
|
|
36
38
|
export { createAuthenticatedLoopbackTransport, createCapabilityToken, createMigrationRecipe, createRealmCapabilityMatrix, createServiceCapability, probeMigrationTarget } from '@forgeax/engine-tool-runtime';
|
|
37
39
|
import { Context, isToolPlugin } from '@forgeax/engine-plugin';
|
|
38
40
|
import { installCatalogLoader, projectPluginEntries, bootstrapCatalogLoader } from '@forgeax/engine-plugin/loader';
|
|
39
|
-
import { createServer
|
|
41
|
+
import { createServer } from 'http';
|
|
40
42
|
import { createToolPreviewRecipe, createToolPreviewHost } from '@forgeax/engine-app';
|
|
41
|
-
import { createServer as createServer$2 } from 'net';
|
|
42
43
|
import { chromium } from 'playwright';
|
|
43
44
|
|
|
44
45
|
var __defProp = Object.defineProperty;
|
|
@@ -303,16 +304,17 @@ var init_dist = __esm({
|
|
|
303
304
|
"src/dist.ts"() {
|
|
304
305
|
}
|
|
305
306
|
});
|
|
307
|
+
|
|
308
|
+
// src/host.ts
|
|
309
|
+
var host_exports = {};
|
|
310
|
+
__export(host_exports, {
|
|
311
|
+
createViteConfig: () => createViteConfig,
|
|
312
|
+
devKitDdcRoots: () => devKitDdcRoots,
|
|
313
|
+
ignoreDevKitCatalogPath: () => ignoreDevKitCatalogPath
|
|
314
|
+
});
|
|
306
315
|
function ignoreDevKitCatalogPath(path) {
|
|
307
316
|
const normalized = path.replace(/\\/g, "/");
|
|
308
|
-
|
|
309
|
-
if (!normalized.endsWith(".meta.json")) return false;
|
|
310
|
-
try {
|
|
311
|
-
const meta = JSON.parse(readFileSync(path, "utf8"));
|
|
312
|
-
return meta.importer === "game-default-target-profile";
|
|
313
|
-
} catch {
|
|
314
|
-
return false;
|
|
315
|
-
}
|
|
317
|
+
return normalized.split("/").includes("shaders");
|
|
316
318
|
}
|
|
317
319
|
function devKitDdcRoots(projectRoot) {
|
|
318
320
|
return {
|
|
@@ -578,17 +580,20 @@ await app.pluginContext.plugin({
|
|
|
578
580
|
return `import { forgeaxBundlerAdapter } from 'virtual:forgeax/bundler';
|
|
579
581
|
import { createApp, createToolPreviewHost, createToolPreviewRecipe, fitToolPreviewCameraToAabb, gameHostPlugin, replayToolPreviewCapture } from '@forgeax/engine/app';
|
|
580
582
|
import { createCatalogSource } from '@forgeax/engine/assets-runtime';
|
|
583
|
+
import {
|
|
584
|
+
createRuntimeAssetImportTransport,
|
|
585
|
+
runtimeBinding,
|
|
586
|
+
} from 'virtual:forgeax/pack-runtime';
|
|
581
587
|
import { installCatalogLoader, projectPluginEntries } from '@forgeax/engine/plugin/loader';
|
|
582
588
|
import { audioPlugin } from '@forgeax/engine/audio';
|
|
583
589
|
import { webAudioPlugin } from '@forgeax/engine/audio-webaudio';
|
|
584
590
|
import { physicsPlugin } from '@forgeax/engine/physics';
|
|
585
591
|
import { skinningPlugin } from '@forgeax/engine/skinning';
|
|
586
592
|
import { createPrimitiveMesh } from '@forgeax/engine/geometry';
|
|
587
|
-
import { createDevImportTransport } from '@forgeax/engine/runtime';
|
|
588
593
|
import { mat4 } from '@forgeax/engine/math';
|
|
589
594
|
import { CAMERA_PROJECTION_ORTHOGRAPHIC, Camera, DirectionalLight, Materials, MeshFilter, MeshRenderer, Skylight, SkyboxBackground, TONEMAP_NONE, TONEMAP_REINHARD_EXTENDED } from '@forgeax/engine/render';
|
|
590
|
-
import {
|
|
591
|
-
import {
|
|
595
|
+
import { Transform } from '@forgeax/engine/scene';
|
|
596
|
+
import { type SceneAsset } from '@forgeax/engine/types';
|
|
592
597
|
import { ParticleEffectPlayer, vfxGpuEffectContribution } from '@forgeax/engine/vfx';
|
|
593
598
|
import { createVfxRuntimeHost } from '@forgeax/engine/vfx-render';
|
|
594
599
|
|
|
@@ -689,17 +694,39 @@ const resizeCanvas = () => {
|
|
|
689
694
|
const resizeObserver = new ResizeObserver(resizeCanvas);
|
|
690
695
|
resizeObserver.observe(canvas);
|
|
691
696
|
resizeCanvas();
|
|
692
|
-
const runtimeScopeBinding =
|
|
697
|
+
const runtimeScopeBinding = runtimeBinding;
|
|
698
|
+
if (runtimeScopeBinding === undefined) {
|
|
699
|
+
throw new Error('forgeax: Vite Pack runtime binding is required in the generated host');
|
|
700
|
+
}
|
|
693
701
|
const assetCatalog = createCatalogSource({
|
|
694
702
|
url: import.meta.env.DEV
|
|
695
703
|
? runtimeScopeBinding.catalogUrl
|
|
696
704
|
: new URL('pack-index.json', document.baseURI).href,
|
|
697
|
-
expectedScope: runtimeScopeBinding,
|
|
705
|
+
...(import.meta.env.DEV ? { expectedScope: runtimeScopeBinding } : {}),
|
|
698
706
|
});
|
|
699
707
|
const bundler = {
|
|
700
708
|
...forgeaxBundlerAdapter(),
|
|
701
|
-
...(import.meta.env.DEV
|
|
709
|
+
...(import.meta.env.DEV
|
|
710
|
+
? { importTransport: createRuntimeAssetImportTransport(runtimeScopeBinding) }
|
|
711
|
+
: {}),
|
|
702
712
|
};
|
|
713
|
+
const assetPreparation = new WeakMap();
|
|
714
|
+
|
|
715
|
+
function prepareAssetRegistry(assets) {
|
|
716
|
+
const existing = assetPreparation.get(assets);
|
|
717
|
+
if (existing !== undefined) return existing;
|
|
718
|
+
const pending = (async () => {
|
|
719
|
+
assets.configureRuntimeBinding(runtimeScopeBinding);
|
|
720
|
+
assets.setCatalogSource(assetCatalog);
|
|
721
|
+
if (vfxRuntimeHost !== undefined) {
|
|
722
|
+
assets.installDecoder(vfxGpuEffectContribution.kind, vfxGpuEffectContribution.decoder);
|
|
723
|
+
}
|
|
724
|
+
const catalog = await assets.enumerateCatalog();
|
|
725
|
+
if (!catalog.ok) throw catalog.error;
|
|
726
|
+
})();
|
|
727
|
+
assetPreparation.set(assets, pending);
|
|
728
|
+
return pending;
|
|
729
|
+
}
|
|
703
730
|
|
|
704
731
|
function previewStable(value) {
|
|
705
732
|
if (value instanceof ArrayBuffer) return 'ArrayBuffer:' + JSON.stringify(Array.from(new Uint8Array(value)));
|
|
@@ -760,13 +787,14 @@ async function previewOwnerFacts(assets, resource, payload) {
|
|
|
760
787
|
}
|
|
761
788
|
|
|
762
789
|
async function prepareProject(app) {
|
|
790
|
+
await prepareAssetRegistry(app.assets);
|
|
763
791
|
previewWorld = app.world;
|
|
764
792
|
const assets = app.assets;
|
|
765
793
|
let canonicalEnvironment;
|
|
766
794
|
if (resource !== undefined) {
|
|
767
795
|
if (resource.kind !== 'texture') {
|
|
768
796
|
if (canonicalEnvironmentGuid === null) throw new Error('canonical preview environment is unavailable');
|
|
769
|
-
const environment = await assets.
|
|
797
|
+
const environment = await assets.loadByGuid(assets.parseGuid(canonicalEnvironmentGuid));
|
|
770
798
|
if (!environment.ok) throw environment.error;
|
|
771
799
|
if (environment.value.kind !== 'equirect') {
|
|
772
800
|
throw new Error(\`canonical preview environment expected equirect, received \${environment.value.kind}\`);
|
|
@@ -781,7 +809,7 @@ if (resource !== undefined) {
|
|
|
781
809
|
const attached = await vfxRuntimeHost.attachWorld({ world: app.world, assets });
|
|
782
810
|
if (!attached.ok) throw attached.error;
|
|
783
811
|
}
|
|
784
|
-
const loaded = await assets.
|
|
812
|
+
const loaded = await assets.loadByGuid(assets.parseGuid(resource.guid));
|
|
785
813
|
if (!loaded.ok) throw loaded.error;
|
|
786
814
|
const payload = loaded.value;
|
|
787
815
|
if (resource.kind === 'vfx' && payload.kind !== 'particle-effect') {
|
|
@@ -794,7 +822,7 @@ if (resource !== undefined) {
|
|
|
794
822
|
const meshMaterialHandles = resource.kind === 'mesh' && payload.kind === 'mesh'
|
|
795
823
|
? await Promise.all(payload.materialSlots.map(async (slot) => {
|
|
796
824
|
if (slot.defaultMaterial === undefined) return 0;
|
|
797
|
-
const material = await assets.
|
|
825
|
+
const material = await assets.loadByGuid(assets.parseGuid(slot.defaultMaterial));
|
|
798
826
|
if (!material.ok) throw material.error;
|
|
799
827
|
if (material.value.kind !== 'material') {
|
|
800
828
|
throw new Error('mesh material slot resolved to a non-material asset');
|
|
@@ -924,15 +952,13 @@ let defaultScene;
|
|
|
924
952
|
let defaultSceneRoot;
|
|
925
953
|
const defaultSceneGuid = ${JSON.stringify(facts.defaultScene)};
|
|
926
954
|
if (defaultSceneGuid !== undefined) {
|
|
927
|
-
const loaded = await assets.
|
|
955
|
+
const loaded = await assets.loadByGuid<SceneAsset>(assets.parseGuid(defaultSceneGuid));
|
|
928
956
|
if (!loaded.ok) throw loaded.error;
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
const handle = app.world.allocSharedRef('SceneAsset', projected.value);
|
|
933
|
-
const instantiated = worldInstantiateScene(app.world, handle);
|
|
957
|
+
defaultScene = loaded.value;
|
|
958
|
+
const handle = app.world.allocSharedRef('SceneAsset', loaded.value);
|
|
959
|
+
const instantiated = assets.instantiate<SceneAsset>(handle, app.world);
|
|
934
960
|
if (!instantiated.ok) throw instantiated.error;
|
|
935
|
-
defaultSceneRoot = instantiated.value
|
|
961
|
+
defaultSceneRoot = instantiated.value;
|
|
936
962
|
}
|
|
937
963
|
const uiRoot = document.querySelector('#game-ui');
|
|
938
964
|
await app.pluginContext.plugin(gameHostPlugin({
|
|
@@ -971,8 +997,6 @@ if (query.has('forgeax-tool-replay')) {
|
|
|
971
997
|
...(resource === undefined ? {} : { resource }),
|
|
972
998
|
canvas,
|
|
973
999
|
app: {
|
|
974
|
-
...(assetCatalog === undefined ? {} : { assetCatalog }),
|
|
975
|
-
...(vfxRuntimeHost === undefined ? {} : { assetDecoders: [vfxGpuEffectContribution] }),
|
|
976
1000
|
plugins: [${plugins.join(", ")}],
|
|
977
1001
|
...(vfxRuntimeHost === undefined ? {} : { features: [vfxRuntimeHost.feature] }),
|
|
978
1002
|
},
|
|
@@ -1085,8 +1109,6 @@ if (query.has('forgeax-tool-replay')) {
|
|
|
1085
1109
|
const result = await createApp(
|
|
1086
1110
|
canvas,
|
|
1087
1111
|
{
|
|
1088
|
-
...(assetCatalog === undefined ? {} : { assetCatalog }),
|
|
1089
|
-
...(vfxRuntimeHost === undefined ? {} : { assetDecoders: [vfxGpuEffectContribution] }),
|
|
1090
1112
|
plugins: [${plugins.join(", ")}],
|
|
1091
1113
|
...(pointerLockAllowed === undefined ? {} : { pointerLockAllowed }),
|
|
1092
1114
|
},
|
|
@@ -1234,9 +1256,9 @@ async function createViteConfig(facts, command, base = "/", options = {}) {
|
|
|
1234
1256
|
plugins,
|
|
1235
1257
|
resolve: {
|
|
1236
1258
|
alias: consumerAliases,
|
|
1237
|
-
dedupe: ["@forgeax/engine
|
|
1259
|
+
dedupe: ["@forgeax/engine"]
|
|
1238
1260
|
},
|
|
1239
|
-
server: { fs: { allow: [facts.root, ...roots] } },
|
|
1261
|
+
server: { ...options.server, fs: { allow: [facts.root, ...roots] } },
|
|
1240
1262
|
build: {
|
|
1241
1263
|
target: "esnext",
|
|
1242
1264
|
outDir: options.outDir ?? resolve(facts.root, "dist"),
|
|
@@ -1260,7 +1282,7 @@ async function readJson(path) {
|
|
|
1260
1282
|
function firstUnsupportedStandaloneRealm(entries2, inheritedRealm = "engine") {
|
|
1261
1283
|
for (const entry of entries2) {
|
|
1262
1284
|
const realm = entry.realm ?? inheritedRealm ?? "engine";
|
|
1263
|
-
if (realm
|
|
1285
|
+
if (realm !== "engine") return { id: entry.id, realm };
|
|
1264
1286
|
if (entry.group === true) {
|
|
1265
1287
|
const unsupported = firstUnsupportedStandaloneRealm(
|
|
1266
1288
|
entry.config,
|
|
@@ -1378,13 +1400,10 @@ async function readProjectFacts(rootInput = process.cwd()) {
|
|
|
1378
1400
|
}
|
|
1379
1401
|
};
|
|
1380
1402
|
}
|
|
1381
|
-
function isCommandError(value) {
|
|
1382
|
-
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
1383
|
-
const candidate = value;
|
|
1384
|
-
return typeof candidate.code === "string" && typeof candidate.expected === "string" && typeof candidate.hint === "string" && candidate.detail !== null && typeof candidate.detail === "object" && !Array.isArray(candidate.detail);
|
|
1385
|
-
}
|
|
1386
1403
|
function commandError(cause, fallbackCode) {
|
|
1387
|
-
if (
|
|
1404
|
+
if (cause !== null && typeof cause === "object" && "code" in cause && "expected" in cause && "hint" in cause && "detail" in cause) {
|
|
1405
|
+
return cause;
|
|
1406
|
+
}
|
|
1388
1407
|
return {
|
|
1389
1408
|
code: fallbackCode,
|
|
1390
1409
|
expected: "the ForgeaX command to complete",
|
|
@@ -1396,16 +1415,17 @@ var init_project = __esm({
|
|
|
1396
1415
|
"src/project.ts"() {
|
|
1397
1416
|
}
|
|
1398
1417
|
});
|
|
1399
|
-
|
|
1400
|
-
|
|
1418
|
+
|
|
1419
|
+
// src/types.ts
|
|
1420
|
+
function resolveProjectPort(port) {
|
|
1421
|
+
return { port: port ?? 5173, strictPort: port !== 0 };
|
|
1401
1422
|
}
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
const parsed = JSON.parse(stderr.at(-1) ?? "");
|
|
1405
|
-
if (isCommandError(parsed)) return failure(parsed);
|
|
1406
|
-
} catch {
|
|
1423
|
+
var init_types = __esm({
|
|
1424
|
+
"src/types.ts"() {
|
|
1407
1425
|
}
|
|
1408
|
-
|
|
1426
|
+
});
|
|
1427
|
+
function failure(error) {
|
|
1428
|
+
return { ok: false, error };
|
|
1409
1429
|
}
|
|
1410
1430
|
async function sourcesAt(path) {
|
|
1411
1431
|
const info = await stat(path);
|
|
@@ -1490,15 +1510,16 @@ async function addGltf(sourcePath, dryRun) {
|
|
|
1490
1510
|
stderrWrite: (line) => stderr.push(line)
|
|
1491
1511
|
});
|
|
1492
1512
|
if (exitCode !== 0) {
|
|
1493
|
-
|
|
1494
|
-
stderr
|
|
1495
|
-
|
|
1513
|
+
try {
|
|
1514
|
+
return failure(JSON.parse(stderr.at(-1) ?? ""));
|
|
1515
|
+
} catch {
|
|
1516
|
+
return failure({
|
|
1496
1517
|
code: "asset-add-failed",
|
|
1497
1518
|
expected: "the glTF producer to create or reuse a valid sidecar",
|
|
1498
|
-
hint: "Inspect the glTF source and its external references."
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1519
|
+
hint: "Inspect the glTF source and its external references.",
|
|
1520
|
+
detail: { source: sourcePath, diagnostic: stderr.join("\n") }
|
|
1521
|
+
});
|
|
1522
|
+
}
|
|
1502
1523
|
}
|
|
1503
1524
|
return { ok: true, value: { source: sourcePath, metaPath: `${sourcePath}.meta.json` } };
|
|
1504
1525
|
}
|
|
@@ -1541,15 +1562,16 @@ async function entries(options) {
|
|
|
1541
1562
|
{ stdoutWrite: (line) => stdout.push(line), stderrWrite: (line) => stderr.push(line) }
|
|
1542
1563
|
);
|
|
1543
1564
|
if (!result.ok) {
|
|
1544
|
-
|
|
1545
|
-
stderr
|
|
1546
|
-
|
|
1565
|
+
try {
|
|
1566
|
+
return failure(JSON.parse(stderr.at(-1) ?? ""));
|
|
1567
|
+
} catch {
|
|
1568
|
+
return failure({
|
|
1547
1569
|
code: "asset-authority-invalid",
|
|
1548
1570
|
expected: "all asset roots and sidecars to pass the pack scanner",
|
|
1549
|
-
hint: "Repair the first invalid asset authority reported by the scanner."
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1571
|
+
hint: "Repair the first invalid asset authority reported by the scanner.",
|
|
1572
|
+
detail: { diagnostic: stderr.join("\n") }
|
|
1573
|
+
});
|
|
1574
|
+
}
|
|
1553
1575
|
}
|
|
1554
1576
|
return { ok: true, value: { facts: facts.value, entries: result.value } };
|
|
1555
1577
|
}
|
|
@@ -1634,7 +1656,6 @@ var init_package = __esm({
|
|
|
1634
1656
|
"@forgeax/engine-audio-webaudio": "workspace:*",
|
|
1635
1657
|
"@forgeax/engine-fbx": "workspace:*",
|
|
1636
1658
|
"@forgeax/engine-font": "workspace:*",
|
|
1637
|
-
"@forgeax/engine-geometry": "workspace:*",
|
|
1638
1659
|
"@forgeax/engine-gltf": "workspace:*",
|
|
1639
1660
|
"@forgeax/engine-image": "workspace:*",
|
|
1640
1661
|
"@forgeax/engine-input": "workspace:*",
|
|
@@ -1644,6 +1665,7 @@ var init_package = __esm({
|
|
|
1644
1665
|
"@forgeax/engine-preview": "workspace:*",
|
|
1645
1666
|
"@forgeax/engine-project": "workspace:*",
|
|
1646
1667
|
"@forgeax/engine-rhi-debug": "workspace:*",
|
|
1668
|
+
"@forgeax/engine-rhi-null": "workspace:*",
|
|
1647
1669
|
"@forgeax/engine-render": "workspace:*",
|
|
1648
1670
|
"@forgeax/engine-render-graph": "workspace:*",
|
|
1649
1671
|
"@forgeax/engine-runtime": "workspace:*",
|
|
@@ -1661,7 +1683,6 @@ var init_package = __esm({
|
|
|
1661
1683
|
vitest: "4.1.5"
|
|
1662
1684
|
},
|
|
1663
1685
|
devDependencies: {
|
|
1664
|
-
"@forgeax/engine-rhi-null": "workspace:*",
|
|
1665
1686
|
"@types/node": "^20.14.0"
|
|
1666
1687
|
},
|
|
1667
1688
|
forgeax: {
|
|
@@ -1875,6 +1896,20 @@ var init_sdk = __esm({
|
|
|
1875
1896
|
"src/sdk.ts"() {
|
|
1876
1897
|
}
|
|
1877
1898
|
});
|
|
1899
|
+
function agentOnboarding(sdk, projectRoot) {
|
|
1900
|
+
const root = projectRoot ?? sdk.root;
|
|
1901
|
+
return {
|
|
1902
|
+
read: [
|
|
1903
|
+
resolve(root, "AGENTS.md"),
|
|
1904
|
+
resolve(root, "skills", "forgeax-engine-sdk", "SKILL.md"),
|
|
1905
|
+
resolve(root, "skills", "forgeax-engine-sdk", "references", "feature-catalog.md")
|
|
1906
|
+
],
|
|
1907
|
+
next: projectRoot === void 0 ? {
|
|
1908
|
+
cwd: root,
|
|
1909
|
+
argv: ["node", "./bin/forgeax.mjs", "new", "../my-game"]
|
|
1910
|
+
} : { cwd: root, argv: ["pnpm", "exec", "forgeax", "list", "--json"] }
|
|
1911
|
+
};
|
|
1912
|
+
}
|
|
1878
1913
|
function sdkInitPath(sdk) {
|
|
1879
1914
|
return resolve(sdk.root, ...SDK_INIT_PATH);
|
|
1880
1915
|
}
|
|
@@ -1889,7 +1924,7 @@ function sdkProjectInstallArgs(store) {
|
|
|
1889
1924
|
"--side-effects-cache=true",
|
|
1890
1925
|
"--child-concurrency=1"
|
|
1891
1926
|
];
|
|
1892
|
-
return store === void 0 ? common : [...common, "--offline", "--trust-lockfile", "--store-dir", store];
|
|
1927
|
+
return store === void 0 ? common : [...common, "--offline", "--config.trust-lockfile=true", "--store-dir", store];
|
|
1893
1928
|
}
|
|
1894
1929
|
function sdkBootstrapInstallArgs(store) {
|
|
1895
1930
|
const common = [
|
|
@@ -1898,7 +1933,7 @@ function sdkBootstrapInstallArgs(store) {
|
|
|
1898
1933
|
"--child-concurrency=1",
|
|
1899
1934
|
"--side-effects-cache=true"
|
|
1900
1935
|
];
|
|
1901
|
-
return store === void 0 ? common : [...common, "--offline", "--trust-lockfile", "--store-dir", store];
|
|
1936
|
+
return store === void 0 ? common : [...common, "--offline", "--config.trust-lockfile=true", "--store-dir", store];
|
|
1902
1937
|
}
|
|
1903
1938
|
function supportedPnpm(version) {
|
|
1904
1939
|
const [major = 0, minor = 0] = version.split(".").map(Number);
|
|
@@ -1988,7 +2023,8 @@ async function sdkInitCommand(sdk, options = {}) {
|
|
|
1988
2023
|
const report = {
|
|
1989
2024
|
...state,
|
|
1990
2025
|
root: sdk.root,
|
|
1991
|
-
store: sdk.store === void 0 ? "registry" : "offline"
|
|
2026
|
+
store: sdk.store === void 0 ? "registry" : "offline",
|
|
2027
|
+
onboarding: agentOnboarding(sdk)
|
|
1992
2028
|
};
|
|
1993
2029
|
if (options.dryRun === true || options.install === false) return { ok: true, value: report };
|
|
1994
2030
|
let staging;
|
|
@@ -2023,6 +2059,107 @@ var init_sdk_bootstrap = __esm({
|
|
|
2023
2059
|
SDK_INIT_SCHEMA_VERSION = "1.0.0";
|
|
2024
2060
|
}
|
|
2025
2061
|
});
|
|
2062
|
+
|
|
2063
|
+
// src/sdk-update.ts
|
|
2064
|
+
function parseVersion(version) {
|
|
2065
|
+
const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(
|
|
2066
|
+
version
|
|
2067
|
+
);
|
|
2068
|
+
if (match === null) return void 0;
|
|
2069
|
+
const major = match[1];
|
|
2070
|
+
const minor = match[2];
|
|
2071
|
+
const patch = match[3];
|
|
2072
|
+
if (major === void 0 || minor === void 0 || patch === void 0) return void 0;
|
|
2073
|
+
const prerelease = match[4]?.split(".");
|
|
2074
|
+
if (prerelease?.some(
|
|
2075
|
+
(identifier) => identifier.length === 0 || /^\d+$/.test(identifier) && /^0\d+/.test(identifier)
|
|
2076
|
+
)) {
|
|
2077
|
+
return void 0;
|
|
2078
|
+
}
|
|
2079
|
+
return {
|
|
2080
|
+
core: [major, minor, patch],
|
|
2081
|
+
...prerelease === void 0 ? {} : { prerelease }
|
|
2082
|
+
};
|
|
2083
|
+
}
|
|
2084
|
+
function compareNumericIdentifier(current, latest) {
|
|
2085
|
+
if (current.length !== latest.length) return latest.length > current.length ? 1 : -1;
|
|
2086
|
+
if (current === latest) return 0;
|
|
2087
|
+
return latest > current ? 1 : -1;
|
|
2088
|
+
}
|
|
2089
|
+
function comparePrerelease(current, latest) {
|
|
2090
|
+
const length = Math.max(current.length, latest.length);
|
|
2091
|
+
for (let index = 0; index < length; index += 1) {
|
|
2092
|
+
const currentIdentifier = current[index];
|
|
2093
|
+
const latestIdentifier = latest[index];
|
|
2094
|
+
if (currentIdentifier === void 0) return 1;
|
|
2095
|
+
if (latestIdentifier === void 0) return -1;
|
|
2096
|
+
if (currentIdentifier === latestIdentifier) continue;
|
|
2097
|
+
const currentNumeric = /^\d+$/.test(currentIdentifier);
|
|
2098
|
+
const latestNumeric = /^\d+$/.test(latestIdentifier);
|
|
2099
|
+
if (currentNumeric && latestNumeric) {
|
|
2100
|
+
return compareNumericIdentifier(currentIdentifier, latestIdentifier);
|
|
2101
|
+
}
|
|
2102
|
+
if (currentNumeric !== latestNumeric) return latestNumeric ? -1 : 1;
|
|
2103
|
+
return latestIdentifier > currentIdentifier ? 1 : -1;
|
|
2104
|
+
}
|
|
2105
|
+
return 0;
|
|
2106
|
+
}
|
|
2107
|
+
function newerSdkVersion(currentVersion, latestVersion) {
|
|
2108
|
+
const current = parseVersion(currentVersion);
|
|
2109
|
+
const latest = parseVersion(latestVersion);
|
|
2110
|
+
if (current === void 0 || latest === void 0) return false;
|
|
2111
|
+
for (let index = 0; index < current.core.length; index += 1) {
|
|
2112
|
+
const precedence = compareNumericIdentifier(
|
|
2113
|
+
current.core[index] ?? "0",
|
|
2114
|
+
latest.core[index] ?? "0"
|
|
2115
|
+
);
|
|
2116
|
+
if (precedence !== 0) return precedence > 0;
|
|
2117
|
+
}
|
|
2118
|
+
if (current.prerelease !== void 0 && latest.prerelease === void 0) return true;
|
|
2119
|
+
if (current.prerelease === void 0 || latest.prerelease === void 0) return false;
|
|
2120
|
+
return comparePrerelease(current.prerelease, latest.prerelease) > 0;
|
|
2121
|
+
}
|
|
2122
|
+
function offline() {
|
|
2123
|
+
return ["1", "true"].includes((process.env.npm_config_offline ?? "").toLowerCase());
|
|
2124
|
+
}
|
|
2125
|
+
async function checkSdkUpdate(currentVersion) {
|
|
2126
|
+
if (process.env.FORGEAX_DISABLE_UPDATE_CHECK === "1") {
|
|
2127
|
+
return { status: "skipped", currentVersion, reason: "disabled" };
|
|
2128
|
+
}
|
|
2129
|
+
if (offline()) return { status: "skipped", currentVersion, reason: "offline" };
|
|
2130
|
+
try {
|
|
2131
|
+
const registry = process.env.npm_config_registry ?? "https://registry.npmjs.org/";
|
|
2132
|
+
const response = await fetch(
|
|
2133
|
+
new URL("@forgeax%2Fengine-sdk", `${registry.replace(/\/$/, "")}/`),
|
|
2134
|
+
{
|
|
2135
|
+
headers: { accept: "application/vnd.npm.install-v1+json" },
|
|
2136
|
+
signal: AbortSignal.timeout(2e3)
|
|
2137
|
+
}
|
|
2138
|
+
);
|
|
2139
|
+
if (!response.ok) throw new Error(`registry-http-${response.status}`);
|
|
2140
|
+
const metadata = await response.json();
|
|
2141
|
+
const latestVersion = metadata["dist-tags"]?.latest;
|
|
2142
|
+
if (typeof latestVersion !== "string") throw new Error("registry-latest-version-missing");
|
|
2143
|
+
return newerSdkVersion(currentVersion, latestVersion) ? {
|
|
2144
|
+
status: "available",
|
|
2145
|
+
currentVersion,
|
|
2146
|
+
latestVersion,
|
|
2147
|
+
migrationRisk: UPDATE_MIGRATION_RISK
|
|
2148
|
+
} : { status: "current", currentVersion, latestVersion };
|
|
2149
|
+
} catch (cause) {
|
|
2150
|
+
return {
|
|
2151
|
+
status: "unavailable",
|
|
2152
|
+
currentVersion,
|
|
2153
|
+
reason: cause instanceof Error ? cause.message : String(cause)
|
|
2154
|
+
};
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
var UPDATE_MIGRATION_RISK;
|
|
2158
|
+
var init_sdk_update = __esm({
|
|
2159
|
+
"src/sdk-update.ts"() {
|
|
2160
|
+
UPDATE_MIGRATION_RISK = "Install a newer SDK in a separate directory. Existing games remain pinned and are not migrated automatically; review release notes and migrate and test each game before changing its Engine version.";
|
|
2161
|
+
}
|
|
2162
|
+
});
|
|
2026
2163
|
function slash(path) {
|
|
2027
2164
|
return path.split(sep).join("/");
|
|
2028
2165
|
}
|
|
@@ -2650,9 +2787,16 @@ async function newCommand(options = {}) {
|
|
|
2650
2787
|
env: { ...process.env, CI: "true" },
|
|
2651
2788
|
maxBuffer: 16 * 1024 * 1024
|
|
2652
2789
|
});
|
|
2790
|
+
const sdkUpdate = await checkSdkUpdate(sdk.manifest.sdkVersion);
|
|
2653
2791
|
return {
|
|
2654
2792
|
ok: true,
|
|
2655
|
-
value: {
|
|
2793
|
+
value: {
|
|
2794
|
+
root,
|
|
2795
|
+
template: templateId,
|
|
2796
|
+
sdkVersion: sdk.manifest.sdkVersion,
|
|
2797
|
+
onboarding: agentOnboarding(sdk, root),
|
|
2798
|
+
sdkUpdate
|
|
2799
|
+
}
|
|
2656
2800
|
};
|
|
2657
2801
|
} catch (cause) {
|
|
2658
2802
|
if (staging !== void 0) await rm(staging, { recursive: true, force: true });
|
|
@@ -2685,6 +2829,7 @@ var init_bootstrap_commands = __esm({
|
|
|
2685
2829
|
init_project();
|
|
2686
2830
|
init_sdk();
|
|
2687
2831
|
init_sdk_bootstrap();
|
|
2832
|
+
init_sdk_update();
|
|
2688
2833
|
init_skill_install();
|
|
2689
2834
|
execFileAsync2 = promisify(execFile);
|
|
2690
2835
|
}
|
|
@@ -2853,491 +2998,12 @@ var init_plugin_authoring = __esm({
|
|
|
2853
2998
|
execFileAsync3 = promisify(execFile);
|
|
2854
2999
|
}
|
|
2855
3000
|
});
|
|
2856
|
-
var RhiError;
|
|
2857
|
-
var init_dist2 = __esm({
|
|
2858
|
-
"../rhi/dist/index.mjs"() {
|
|
2859
|
-
RhiError = class extends Error {
|
|
2860
|
-
code;
|
|
2861
|
-
expected;
|
|
2862
|
-
hint;
|
|
2863
|
-
detail;
|
|
2864
|
-
constructor(args) {
|
|
2865
|
-
super(`[RhiError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);
|
|
2866
|
-
this.name = "RhiError";
|
|
2867
|
-
this.code = args.code;
|
|
2868
|
-
this.expected = args.expected;
|
|
2869
|
-
this.hint = args.hint;
|
|
2870
|
-
this.detail = args.detail;
|
|
2871
|
-
}
|
|
2872
|
-
};
|
|
2873
|
-
}
|
|
2874
|
-
});
|
|
2875
|
-
function readPassLabel(desc) {
|
|
2876
|
-
if (desc && typeof desc.label === "string" && desc.label.length > 0) {
|
|
2877
|
-
return desc.label;
|
|
2878
|
-
}
|
|
2879
|
-
return "<unnamed>";
|
|
2880
|
-
}
|
|
2881
|
-
function readRecord(handle) {
|
|
2882
|
-
if (handle === null || typeof handle !== "object") return void 0;
|
|
2883
|
-
const tagged = handle;
|
|
2884
|
-
return tagged[BOOKKEEPING_KEY];
|
|
2885
|
-
}
|
|
2886
|
-
function isHandleDestroyed(handle) {
|
|
2887
|
-
if (readRecord(handle)?.destroyed === true) {
|
|
2888
|
-
return err(
|
|
2889
|
-
new RhiError({
|
|
2890
|
-
code: "destroy-after-destroy",
|
|
2891
|
-
expected: "GPU buffer/texture handle has not been destroyed yet",
|
|
2892
|
-
hint: "object already destroyed; track lifecycle in caller or check isDestroyed before re-destroy"
|
|
2893
|
-
})
|
|
2894
|
-
);
|
|
2895
|
-
}
|
|
2896
|
-
return ok(void 0);
|
|
2897
|
-
}
|
|
2898
|
-
function acquireCanvasContext(_canvas) {
|
|
2899
|
-
return ok(new RhiNullCanvasContext());
|
|
2900
|
-
}
|
|
2901
|
-
function createShaderModule(_device, _desc) {
|
|
2902
|
-
return Promise.resolve(ok({}));
|
|
2903
|
-
}
|
|
2904
|
-
function requestAdapter(_opts, _compatibleSurface) {
|
|
2905
|
-
return Promise.resolve(ok(new RhiNullAdapter()));
|
|
2906
|
-
}
|
|
2907
|
-
var RhiNullRenderPassEncoder, RhiNullComputePassEncoder, DeviceCounter, RhiNullCommandEncoder, BOOKKEEPING_KEY, Bookkeeper, nextDeviceId, RhiNullDevice, EMPTY_FEATURES, EMPTY_LIMITS, NEVER, RhiNullQueue, RhiNullAdapter, RhiNullCanvasContext, rhi;
|
|
2908
|
-
var init_dist3 = __esm({
|
|
2909
|
-
"../rhi-null/dist/index.mjs"() {
|
|
2910
|
-
init_dist2();
|
|
2911
|
-
RhiNullRenderPassEncoder = class {
|
|
2912
|
-
/** Number of draw* calls issued on this pass (AC-06 readback). */
|
|
2913
|
-
drawCount = 0;
|
|
2914
|
-
bindGroupCount = 0;
|
|
2915
|
-
/** Most recent setVertexBuffer / setBindGroup ownership validation; ok unless
|
|
2916
|
-
* a foreign handle was passed (AC-09 readback). */
|
|
2917
|
-
lastValidation = ok(void 0);
|
|
2918
|
-
bookkeeper;
|
|
2919
|
-
counter;
|
|
2920
|
-
passName;
|
|
2921
|
-
constructor(bookkeeper, counter, passName) {
|
|
2922
|
-
this.bookkeeper = bookkeeper;
|
|
2923
|
-
this.counter = counter;
|
|
2924
|
-
this.passName = passName;
|
|
2925
|
-
}
|
|
2926
|
-
setPipeline(_pipeline) {
|
|
2927
|
-
}
|
|
2928
|
-
setVertexBuffer(_slot, buffer, _offset, _size) {
|
|
2929
|
-
this.lastValidation = this.bookkeeper.validateOwnership(buffer);
|
|
2930
|
-
}
|
|
2931
|
-
setIndexBuffer(_buffer, _format, _offset, _size) {
|
|
2932
|
-
}
|
|
2933
|
-
setBindGroup(_index, bindGroup, _dynamicOffsetsData, _dynamicOffsetsDataStart, _dynamicOffsetsDataLength) {
|
|
2934
|
-
this.bindGroupCount++;
|
|
2935
|
-
this.counter?.recordBindGroup();
|
|
2936
|
-
this.lastValidation = this.bookkeeper.validateOwnership(bindGroup);
|
|
2937
|
-
}
|
|
2938
|
-
draw(_vertexCount, _instanceCount, _firstVertex, _firstInstance) {
|
|
2939
|
-
this.drawCount++;
|
|
2940
|
-
this.counter?.recordDraw();
|
|
2941
|
-
}
|
|
2942
|
-
drawIndexed(_indexCount, _instanceCount, _firstIndex, _baseVertex, _firstInstance) {
|
|
2943
|
-
this.drawCount++;
|
|
2944
|
-
this.counter?.recordDraw();
|
|
2945
|
-
}
|
|
2946
|
-
end() {
|
|
2947
|
-
this.counter?.recordPassName(this.passName);
|
|
2948
|
-
}
|
|
2949
|
-
setViewport(_x, _y, _w, _h, _minDepth, _maxDepth) {
|
|
2950
|
-
}
|
|
2951
|
-
setScissorRect(_x, _y, _w, _h) {
|
|
2952
|
-
}
|
|
2953
|
-
setBlendConstant(_color) {
|
|
2954
|
-
}
|
|
2955
|
-
setStencilReference(_reference) {
|
|
2956
|
-
}
|
|
2957
|
-
drawIndirect(_indirectBuffer, _indirectOffset) {
|
|
2958
|
-
this.drawCount++;
|
|
2959
|
-
this.counter?.recordDraw();
|
|
2960
|
-
}
|
|
2961
|
-
drawIndexedIndirect(_indirectBuffer, _indirectOffset) {
|
|
2962
|
-
this.drawCount++;
|
|
2963
|
-
this.counter?.recordDraw();
|
|
2964
|
-
}
|
|
2965
|
-
pushDebugGroup(_groupLabel) {
|
|
2966
|
-
}
|
|
2967
|
-
popDebugGroup() {
|
|
2968
|
-
}
|
|
2969
|
-
insertDebugMarker(_markerLabel) {
|
|
2970
|
-
}
|
|
2971
|
-
executeBundles(_bundles) {
|
|
2972
|
-
return ok(void 0);
|
|
2973
|
-
}
|
|
2974
|
-
beginOcclusionQuery(_queryIndex) {
|
|
2975
|
-
return ok(void 0);
|
|
2976
|
-
}
|
|
2977
|
-
endOcclusionQuery() {
|
|
2978
|
-
return ok(void 0);
|
|
2979
|
-
}
|
|
2980
|
-
};
|
|
2981
|
-
RhiNullComputePassEncoder = class {
|
|
2982
|
-
/** Number of dispatchWorkgroups calls issued on this pass (readback). */
|
|
2983
|
-
dispatchCount = 0;
|
|
2984
|
-
/** Most recent setBindGroup ownership validation (AC-09 readback). */
|
|
2985
|
-
lastValidation = ok(void 0);
|
|
2986
|
-
bookkeeper;
|
|
2987
|
-
counter;
|
|
2988
|
-
passName;
|
|
2989
|
-
constructor(bookkeeper, counter, passName) {
|
|
2990
|
-
this.bookkeeper = bookkeeper;
|
|
2991
|
-
this.counter = counter;
|
|
2992
|
-
this.passName = passName;
|
|
2993
|
-
}
|
|
2994
|
-
setPipeline(_pipeline) {
|
|
2995
|
-
}
|
|
2996
|
-
setBindGroup(_index, bindGroup, _dynamicOffsets) {
|
|
2997
|
-
this.lastValidation = this.bookkeeper.validateOwnership(bindGroup);
|
|
2998
|
-
}
|
|
2999
|
-
dispatchWorkgroups(_x, _y, _z) {
|
|
3000
|
-
this.dispatchCount++;
|
|
3001
|
-
this.counter?.recordDispatch();
|
|
3002
|
-
}
|
|
3003
|
-
dispatchWorkgroupsIndirect(indirectBuffer, _indirectOffset) {
|
|
3004
|
-
this.lastValidation = this.bookkeeper.validateOwnership(indirectBuffer);
|
|
3005
|
-
this.dispatchCount++;
|
|
3006
|
-
this.counter?.recordDispatch();
|
|
3007
|
-
}
|
|
3008
|
-
end() {
|
|
3009
|
-
this.counter?.recordPassName(this.passName);
|
|
3010
|
-
}
|
|
3011
|
-
};
|
|
3012
|
-
DeviceCounter = class {
|
|
3013
|
-
constructor(device) {
|
|
3014
|
-
this.device = device;
|
|
3015
|
-
}
|
|
3016
|
-
device;
|
|
3017
|
-
recordDraw() {
|
|
3018
|
-
this.device.totalDrawCount++;
|
|
3019
|
-
}
|
|
3020
|
-
recordDispatch() {
|
|
3021
|
-
this.device.totalDispatchCount++;
|
|
3022
|
-
}
|
|
3023
|
-
recordBindGroup() {
|
|
3024
|
-
this.device.totalBindGroupCount++;
|
|
3025
|
-
}
|
|
3026
|
-
recordPassName(name) {
|
|
3027
|
-
this.device.framePassNames.push(name);
|
|
3028
|
-
}
|
|
3029
|
-
};
|
|
3030
|
-
RhiNullCommandEncoder = class {
|
|
3031
|
-
bookkeeper;
|
|
3032
|
-
counter;
|
|
3033
|
-
constructor(bookkeeper, device) {
|
|
3034
|
-
this.bookkeeper = bookkeeper;
|
|
3035
|
-
this.counter = new DeviceCounter(device);
|
|
3036
|
-
}
|
|
3037
|
-
beginRenderPass(desc) {
|
|
3038
|
-
const label = readPassLabel(desc);
|
|
3039
|
-
return new RhiNullRenderPassEncoder(this.bookkeeper, this.counter, label);
|
|
3040
|
-
}
|
|
3041
|
-
beginComputePass(desc) {
|
|
3042
|
-
const label = readPassLabel(desc);
|
|
3043
|
-
return new RhiNullComputePassEncoder(this.bookkeeper, this.counter, label);
|
|
3044
|
-
}
|
|
3045
|
-
copyBufferToBuffer(_source, _sourceOffsetOrDestination, _destinationOrSize, _destinationOffset, _size) {
|
|
3046
|
-
}
|
|
3047
|
-
copyBufferToTexture(_source, _destination, _copySize) {
|
|
3048
|
-
}
|
|
3049
|
-
copyTextureToBuffer(_source, _destination, _copySize) {
|
|
3050
|
-
}
|
|
3051
|
-
copyTextureToTexture(_source, _destination, _copySize) {
|
|
3052
|
-
}
|
|
3053
|
-
clearBuffer(_buffer, _offset, _size) {
|
|
3054
|
-
}
|
|
3055
|
-
resolveQuerySet(_querySet, _firstQuery, _queryCount, _destination, _destinationOffset) {
|
|
3056
|
-
return ok(void 0);
|
|
3057
|
-
}
|
|
3058
|
-
writeTimestamp(_querySet, _queryIndex) {
|
|
3059
|
-
}
|
|
3060
|
-
pushDebugGroup(_groupLabel) {
|
|
3061
|
-
}
|
|
3062
|
-
popDebugGroup() {
|
|
3063
|
-
}
|
|
3064
|
-
insertDebugMarker(_markerLabel) {
|
|
3065
|
-
}
|
|
3066
|
-
finish() {
|
|
3067
|
-
return ok(this.bookkeeper.register("CommandBuffer"));
|
|
3068
|
-
}
|
|
3069
|
-
};
|
|
3070
|
-
BOOKKEEPING_KEY = /* @__PURE__ */ Symbol("forgeax-rhi-null-bookkeeping");
|
|
3071
|
-
Bookkeeper = class {
|
|
3072
|
-
deviceId;
|
|
3073
|
-
nextHandleId = 0;
|
|
3074
|
-
records = /* @__PURE__ */ new Map();
|
|
3075
|
-
constructor(deviceId) {
|
|
3076
|
-
this.deviceId = deviceId;
|
|
3077
|
-
}
|
|
3078
|
-
/**
|
|
3079
|
-
* Register a freshly-minted handle of the given kind, returning a plain
|
|
3080
|
-
* object that carries its ledger row. The caller casts the return value to
|
|
3081
|
-
* the concrete brand (`as unknown as Buffer` etc.).
|
|
3082
|
-
*/
|
|
3083
|
-
register(kind) {
|
|
3084
|
-
const id = this.nextHandleId++;
|
|
3085
|
-
const record = {
|
|
3086
|
-
id,
|
|
3087
|
-
kind,
|
|
3088
|
-
destroyed: false,
|
|
3089
|
-
sourceDeviceId: this.deviceId
|
|
3090
|
-
};
|
|
3091
|
-
this.records.set(id, record);
|
|
3092
|
-
return { [BOOKKEEPING_KEY]: record };
|
|
3093
|
-
}
|
|
3094
|
-
/**
|
|
3095
|
-
* Mark a handle destroyed. Fail-fasts on a second destroy
|
|
3096
|
-
* ('destroy-after-destroy') or on a handle issued by a different device
|
|
3097
|
-
* ('rhi-not-available'); otherwise flips the destroyed flag and returns ok.
|
|
3098
|
-
*/
|
|
3099
|
-
destroy(handle) {
|
|
3100
|
-
const ownership = this.validateOwnership(handle);
|
|
3101
|
-
if (!ownership.ok) return ownership;
|
|
3102
|
-
const destroyedCheck = isHandleDestroyed(handle);
|
|
3103
|
-
if (!destroyedCheck.ok) return destroyedCheck;
|
|
3104
|
-
ownership.value.destroyed = true;
|
|
3105
|
-
return ok(void 0);
|
|
3106
|
-
}
|
|
3107
|
-
/**
|
|
3108
|
-
* Report whether a handle has already been destroyed (true once destroy()
|
|
3109
|
-
* has flipped its flag). Used by command-stream methods that must not
|
|
3110
|
-
* consume a stale handle.
|
|
3111
|
-
*/
|
|
3112
|
-
isDestroyed(handle) {
|
|
3113
|
-
return readRecord(handle)?.destroyed === true;
|
|
3114
|
-
}
|
|
3115
|
-
/**
|
|
3116
|
-
* Validate that a handle was issued by THIS device. Returns the ledger row on
|
|
3117
|
-
* success so callers can mutate it (e.g. flip destroyed); returns
|
|
3118
|
-
* 'rhi-not-available' for a foreign handle (AC-09 — no silent pass).
|
|
3119
|
-
*/
|
|
3120
|
-
validateOwnership(handle) {
|
|
3121
|
-
const record = readRecord(handle);
|
|
3122
|
-
if (record === void 0 || record.sourceDeviceId !== this.deviceId) {
|
|
3123
|
-
return err(
|
|
3124
|
-
new RhiError({
|
|
3125
|
-
code: "rhi-not-available",
|
|
3126
|
-
expected: "handle was issued by this RhiNull device",
|
|
3127
|
-
hint: "do not pass a handle created on a different RhiNull device into this device; create resources on the device they are used with"
|
|
3128
|
-
})
|
|
3129
|
-
);
|
|
3130
|
-
}
|
|
3131
|
-
return ok(record);
|
|
3132
|
-
}
|
|
3133
|
-
/**
|
|
3134
|
-
* Return all ledger rows as a readonly array. M3 unit tests (w17) read this
|
|
3135
|
-
* to assert create/destroy pairing, BGL/PSO shape counts, and resource
|
|
3136
|
-
* lifecycle coverage (AC-05/06/07). Returns a snapshot of the current Map
|
|
3137
|
-
* so callers can iterate without a stale reference after further mutations.
|
|
3138
|
-
*/
|
|
3139
|
-
allRecords() {
|
|
3140
|
-
return [...this.records.values()];
|
|
3141
|
-
}
|
|
3142
|
-
/** Report the total number of records in the ledger. */
|
|
3143
|
-
recordCount() {
|
|
3144
|
-
return this.records.size;
|
|
3145
|
-
}
|
|
3146
|
-
};
|
|
3147
|
-
nextDeviceId = 0;
|
|
3148
|
-
RhiNullDevice = class {
|
|
3149
|
-
internalBookkeeper;
|
|
3150
|
-
nullQueue;
|
|
3151
|
-
encoderFactory;
|
|
3152
|
-
/** Per-frame total draw count across all pass encoders executed this frame
|
|
3153
|
-
* (aggregated by the command encoder on finish, then reset). M3 unit tests
|
|
3154
|
-
* (w17) read this to assert draw count >= 1 (AC-06). */
|
|
3155
|
-
totalDrawCount = 0;
|
|
3156
|
-
/** Per-frame total direct and indirect compute dispatch count. */
|
|
3157
|
-
totalDispatchCount = 0;
|
|
3158
|
-
/** Per-frame total bind group set count (AC-06 / AC-05 readback). */
|
|
3159
|
-
totalBindGroupCount = 0;
|
|
3160
|
-
/** Per-frame pass names executed this frame, in schedule order (AC-04). */
|
|
3161
|
-
framePassNames = [];
|
|
3162
|
-
/** The per-device handle ledger — exposed so M3 tests can assert create/destroy
|
|
3163
|
-
* pairing and BGL/PSO shape counts (AC-05/06/07). */
|
|
3164
|
-
get bookkeeper() {
|
|
3165
|
-
return this.internalBookkeeper;
|
|
3166
|
-
}
|
|
3167
|
-
constructor(queue, encoderFactory) {
|
|
3168
|
-
this.internalBookkeeper = new Bookkeeper(nextDeviceId++);
|
|
3169
|
-
this.nullQueue = queue;
|
|
3170
|
-
this.encoderFactory = encoderFactory;
|
|
3171
|
-
}
|
|
3172
|
-
get caps() {
|
|
3173
|
-
return {
|
|
3174
|
-
backendKind: "null",
|
|
3175
|
-
compute: true,
|
|
3176
|
-
timestampQuery: false,
|
|
3177
|
-
timestampPeriodNanoseconds: null,
|
|
3178
|
-
indirectDrawing: true,
|
|
3179
|
-
textureCompressionBc: false,
|
|
3180
|
-
textureCompressionEtc2: false,
|
|
3181
|
-
textureCompressionAstc: false,
|
|
3182
|
-
// 3 wgpu-native-only reserved flags stay false on non-native backends
|
|
3183
|
-
// (D-5); the headless backend is not a native runtime.
|
|
3184
|
-
multiDrawIndirect: false,
|
|
3185
|
-
pushConstants: false,
|
|
3186
|
-
textureBindingArray: false,
|
|
3187
|
-
samplerAliasing: true,
|
|
3188
|
-
firstInstanceIndirect: true,
|
|
3189
|
-
storageBuffer: true,
|
|
3190
|
-
storageTexture: true,
|
|
3191
|
-
rgba16floatRenderable: true,
|
|
3192
|
-
rg11b10ufloatRenderable: true,
|
|
3193
|
-
float32Filterable: true,
|
|
3194
|
-
maxColorAttachments: 8
|
|
3195
|
-
};
|
|
3196
|
-
}
|
|
3197
|
-
get features() {
|
|
3198
|
-
return EMPTY_FEATURES;
|
|
3199
|
-
}
|
|
3200
|
-
get limits() {
|
|
3201
|
-
return EMPTY_LIMITS;
|
|
3202
|
-
}
|
|
3203
|
-
get queue() {
|
|
3204
|
-
return this.nullQueue;
|
|
3205
|
-
}
|
|
3206
|
-
// forgeax-async-whitelist: dom-native — spec `GPUDevice.lost` Promise
|
|
3207
|
-
// passthrough. The headless backend never loses a device (no GPU), so the
|
|
3208
|
-
// Promise stays unsettled for the lifetime of the device, mirroring a live
|
|
3209
|
-
// device that never transitions to the lost state.
|
|
3210
|
-
get lost() {
|
|
3211
|
-
return NEVER;
|
|
3212
|
-
}
|
|
3213
|
-
createBuffer(_desc) {
|
|
3214
|
-
return ok(this.internalBookkeeper.register("Buffer"));
|
|
3215
|
-
}
|
|
3216
|
-
createTexture(_desc) {
|
|
3217
|
-
return ok(this.internalBookkeeper.register("Texture"));
|
|
3218
|
-
}
|
|
3219
|
-
destroyBuffer(buf) {
|
|
3220
|
-
return this.internalBookkeeper.destroy(buf);
|
|
3221
|
-
}
|
|
3222
|
-
destroyQuerySet(querySet) {
|
|
3223
|
-
return this.internalBookkeeper.destroy(querySet);
|
|
3224
|
-
}
|
|
3225
|
-
destroyTexture(tex) {
|
|
3226
|
-
return this.internalBookkeeper.destroy(tex);
|
|
3227
|
-
}
|
|
3228
|
-
createTextureView(_texture, _desc) {
|
|
3229
|
-
return ok(this.internalBookkeeper.register("TextureView"));
|
|
3230
|
-
}
|
|
3231
|
-
createSampler(_desc) {
|
|
3232
|
-
return ok(this.internalBookkeeper.register("Sampler"));
|
|
3233
|
-
}
|
|
3234
|
-
createBindGroupLayout(_desc) {
|
|
3235
|
-
return ok(this.internalBookkeeper.register("BindGroupLayout"));
|
|
3236
|
-
}
|
|
3237
|
-
createBindGroup(_desc) {
|
|
3238
|
-
return ok(this.internalBookkeeper.register("BindGroup"));
|
|
3239
|
-
}
|
|
3240
|
-
createPipelineLayout(_desc) {
|
|
3241
|
-
return ok(this.internalBookkeeper.register("PipelineLayout"));
|
|
3242
|
-
}
|
|
3243
|
-
createRenderPipeline(_desc) {
|
|
3244
|
-
return ok(this.makePipeline("RenderPipeline"));
|
|
3245
|
-
}
|
|
3246
|
-
createComputePipeline(_desc) {
|
|
3247
|
-
return ok(this.makePipeline("ComputePipeline"));
|
|
3248
|
-
}
|
|
3249
|
-
createQuerySet(desc) {
|
|
3250
|
-
if (desc.type === "timestamp") {
|
|
3251
|
-
return err(
|
|
3252
|
-
new RhiError({
|
|
3253
|
-
code: "feature-not-enabled",
|
|
3254
|
-
expected: "caps.timestampQuery === true (timestamp-query feature)",
|
|
3255
|
-
hint: "RhiNull is structural-only and cannot produce GPU timestamp ticks"
|
|
3256
|
-
})
|
|
3257
|
-
);
|
|
3258
|
-
}
|
|
3259
|
-
return ok(this.internalBookkeeper.register("QuerySet"));
|
|
3260
|
-
}
|
|
3261
|
-
createCommandEncoder(_desc) {
|
|
3262
|
-
return ok(this.encoderFactory(this.internalBookkeeper, this));
|
|
3263
|
-
}
|
|
3264
|
-
/**
|
|
3265
|
-
* Mint a pipeline handle whose object also carries the no-op
|
|
3266
|
-
* `getBindGroupLayout(index)` ops method (D-2). The prod auto-layout path
|
|
3267
|
-
* (debug-draw.ts) and the existing mock unit tests both call
|
|
3268
|
-
* `pipeline.getBindGroupLayout(n)`; returning a legal BindGroupLayout brand
|
|
3269
|
-
* (recorded in the ledger) keeps those consumers from crashing on a missing
|
|
3270
|
-
* method.
|
|
3271
|
-
*/
|
|
3272
|
-
makePipeline(kind) {
|
|
3273
|
-
const handle = this.internalBookkeeper.register(kind);
|
|
3274
|
-
const getBindGroupLayout = (_index) => this.internalBookkeeper.register("BindGroupLayout");
|
|
3275
|
-
return Object.assign(handle, { getBindGroupLayout });
|
|
3276
|
-
}
|
|
3277
|
-
};
|
|
3278
|
-
EMPTY_FEATURES = /* @__PURE__ */ new Set();
|
|
3279
|
-
EMPTY_LIMITS = {};
|
|
3280
|
-
NEVER = new Promise(() => {
|
|
3281
|
-
});
|
|
3282
|
-
RhiNullQueue = class {
|
|
3283
|
-
writeBuffer(_buffer, _bufferOffset, _data, _dataOffset, _size) {
|
|
3284
|
-
return ok(void 0);
|
|
3285
|
-
}
|
|
3286
|
-
writeTexture(_destination, _data, _dataLayout, _size) {
|
|
3287
|
-
return ok(void 0);
|
|
3288
|
-
}
|
|
3289
|
-
copyExternalImageToTexture(_source, _destination, _copySize) {
|
|
3290
|
-
return ok(void 0);
|
|
3291
|
-
}
|
|
3292
|
-
submit(_commandBuffers) {
|
|
3293
|
-
return ok(void 0);
|
|
3294
|
-
}
|
|
3295
|
-
// forgeax-async-whitelist: dom-native — spec `GPUQueue.onSubmittedWorkDone`
|
|
3296
|
-
// never rejects. The headless backend has no pending GPU work, so it resolves
|
|
3297
|
-
// immediately (AC-12: read-back idioms must not hang).
|
|
3298
|
-
onSubmittedWorkDone() {
|
|
3299
|
-
return Promise.resolve(void 0);
|
|
3300
|
-
}
|
|
3301
|
-
};
|
|
3302
|
-
RhiNullAdapter = class {
|
|
3303
|
-
features = /* @__PURE__ */ new Set();
|
|
3304
|
-
limits = {};
|
|
3305
|
-
// forgeax-async-whitelist is not needed: this returns Promise<Result<...>>
|
|
3306
|
-
// per the spec contract; never rejects.
|
|
3307
|
-
requestDevice(_opts) {
|
|
3308
|
-
const device = new RhiNullDevice(
|
|
3309
|
-
new RhiNullQueue(),
|
|
3310
|
-
(bookkeeper, dev) => new RhiNullCommandEncoder(bookkeeper, dev)
|
|
3311
|
-
);
|
|
3312
|
-
return Promise.resolve(ok(device));
|
|
3313
|
-
}
|
|
3314
|
-
};
|
|
3315
|
-
RhiNullCanvasContext = class {
|
|
3316
|
-
configure(_desc) {
|
|
3317
|
-
return ok(void 0);
|
|
3318
|
-
}
|
|
3319
|
-
unconfigure() {
|
|
3320
|
-
}
|
|
3321
|
-
getConfiguration() {
|
|
3322
|
-
return void 0;
|
|
3323
|
-
}
|
|
3324
|
-
getCurrentTexture() {
|
|
3325
|
-
return ok({});
|
|
3326
|
-
}
|
|
3327
|
-
};
|
|
3328
|
-
rhi = {
|
|
3329
|
-
requestAdapter,
|
|
3330
|
-
acquireCanvasContext,
|
|
3331
|
-
createShaderModule
|
|
3332
|
-
};
|
|
3333
|
-
}
|
|
3334
|
-
});
|
|
3335
3001
|
function createCliRhiDebugOperationContext() {
|
|
3336
3002
|
return {
|
|
3337
3003
|
captureFrame: async () => err(
|
|
3338
3004
|
createRhiDebugError("capture-unavailable", {
|
|
3339
3005
|
stage: "capture",
|
|
3340
|
-
cause: "the standalone CLI has no live App capture provider"
|
|
3006
|
+
cause: "the standalone CLI has no live App capture provider; start a recorder-enabled live host and invoke its rhiCapture root"
|
|
3341
3007
|
})
|
|
3342
3008
|
),
|
|
3343
3009
|
async readArtifact(artifact) {
|
|
@@ -3400,7 +3066,6 @@ function createCliRhiDebugOperationContext() {
|
|
|
3400
3066
|
}
|
|
3401
3067
|
var init_cli_context = __esm({
|
|
3402
3068
|
"src/rhi-debug/cli-context.ts"() {
|
|
3403
|
-
init_dist3();
|
|
3404
3069
|
}
|
|
3405
3070
|
});
|
|
3406
3071
|
function createRhiDebugOperationContext(host) {
|
|
@@ -3738,7 +3403,15 @@ async function sdkInstallCommand(options) {
|
|
|
3738
3403
|
await rename(resolve(staging, name), resolve(root, name));
|
|
3739
3404
|
}
|
|
3740
3405
|
}
|
|
3741
|
-
return {
|
|
3406
|
+
return {
|
|
3407
|
+
ok: true,
|
|
3408
|
+
value: {
|
|
3409
|
+
root,
|
|
3410
|
+
sdkVersion: version,
|
|
3411
|
+
source: "@forgeax/engine-sdk",
|
|
3412
|
+
next: { cwd: root, argv: ["node", "./bin/forgeax.mjs", "init"] }
|
|
3413
|
+
}
|
|
3414
|
+
};
|
|
3742
3415
|
} catch (cause) {
|
|
3743
3416
|
return { ok: false, error: commandError(cause, "sdk-install-failed") };
|
|
3744
3417
|
} finally {
|
|
@@ -3821,6 +3494,21 @@ __export(commands_exports, {
|
|
|
3821
3494
|
function runRhiDebugCommand(name, input, context) {
|
|
3822
3495
|
return runRhiDebugOperation(name, input, context);
|
|
3823
3496
|
}
|
|
3497
|
+
async function materializeViteDevPort(port) {
|
|
3498
|
+
if (port !== 0) return port;
|
|
3499
|
+
const reservation = createServer$1();
|
|
3500
|
+
await new Promise((resolveListen, rejectListen) => {
|
|
3501
|
+
reservation.once("error", rejectListen);
|
|
3502
|
+
reservation.listen(0, "127.0.0.1", resolveListen);
|
|
3503
|
+
});
|
|
3504
|
+
const address = reservation.address();
|
|
3505
|
+
const assigned = typeof address === "object" && address !== null ? address.port : 0;
|
|
3506
|
+
await new Promise((resolveClose, rejectClose) => {
|
|
3507
|
+
reservation.close((error) => error === void 0 ? resolveClose() : rejectClose(error));
|
|
3508
|
+
});
|
|
3509
|
+
if (assigned === 0) throw new Error("OS did not assign an ephemeral preview port");
|
|
3510
|
+
return assigned;
|
|
3511
|
+
}
|
|
3824
3512
|
async function buildCommand(options = {}) {
|
|
3825
3513
|
const facts = await readProjectFacts(options.root);
|
|
3826
3514
|
if (!facts.ok) return facts;
|
|
@@ -3923,13 +3611,38 @@ async function devCommand(options = {}) {
|
|
|
3923
3611
|
const facts = await readProjectFacts(options.root);
|
|
3924
3612
|
if (!facts.ok) return facts;
|
|
3925
3613
|
const previous = process.cwd();
|
|
3614
|
+
let server;
|
|
3926
3615
|
try {
|
|
3616
|
+
const { createServer: createServer5 } = await import('vite');
|
|
3617
|
+
const { createViteConfig: createViteConfig2 } = await Promise.resolve().then(() => (init_host(), host_exports));
|
|
3618
|
+
const port = resolveProjectPort(options.port);
|
|
3619
|
+
const vitePort = { ...port, port: await materializeViteDevPort(port.port) };
|
|
3927
3620
|
process.chdir(facts.value.root);
|
|
3928
|
-
|
|
3929
|
-
|
|
3621
|
+
server = await createServer5(
|
|
3622
|
+
await createViteConfig2(facts.value, "serve", "/", {
|
|
3623
|
+
server: vitePort
|
|
3624
|
+
})
|
|
3625
|
+
);
|
|
3626
|
+
await server.listen(vitePort.port);
|
|
3930
3627
|
if (options.json !== true) server.printUrls();
|
|
3931
|
-
return {
|
|
3628
|
+
return {
|
|
3629
|
+
ok: true,
|
|
3630
|
+
value: {
|
|
3631
|
+
root: facts.value.root,
|
|
3632
|
+
urls: server.resolvedUrls,
|
|
3633
|
+
mode: "dev",
|
|
3634
|
+
serves: "source",
|
|
3635
|
+
capabilities: {
|
|
3636
|
+
"rhi.capture": {
|
|
3637
|
+
available: false,
|
|
3638
|
+
realm: "host",
|
|
3639
|
+
reason: "standalone-dev-server-has-no-live-app-cli-attachment"
|
|
3640
|
+
}
|
|
3641
|
+
}
|
|
3642
|
+
}
|
|
3643
|
+
};
|
|
3932
3644
|
} catch (cause) {
|
|
3645
|
+
await server?.close();
|
|
3933
3646
|
process.chdir(previous);
|
|
3934
3647
|
return { ok: false, error: commandError(cause, "dev-server-failed") };
|
|
3935
3648
|
}
|
|
@@ -3939,15 +3652,31 @@ async function previewCommand(options = {}) {
|
|
|
3939
3652
|
const verified = await verifyDist(resolve(root, "dist"));
|
|
3940
3653
|
if (!verified.ok) return verified;
|
|
3941
3654
|
try {
|
|
3655
|
+
const port = resolveProjectPort(options.port);
|
|
3942
3656
|
const server = await preview({
|
|
3943
3657
|
root,
|
|
3944
3658
|
configFile: false,
|
|
3945
3659
|
base: verified.value.base,
|
|
3946
|
-
preview: { open: false, port
|
|
3660
|
+
preview: { open: false, ...port },
|
|
3947
3661
|
build: { outDir: resolve(root, "dist") }
|
|
3948
3662
|
});
|
|
3949
3663
|
if (options.json !== true) server.printUrls();
|
|
3950
|
-
return {
|
|
3664
|
+
return {
|
|
3665
|
+
ok: true,
|
|
3666
|
+
value: {
|
|
3667
|
+
root,
|
|
3668
|
+
urls: server.resolvedUrls,
|
|
3669
|
+
mode: "preview",
|
|
3670
|
+
serves: "dist",
|
|
3671
|
+
capabilities: {
|
|
3672
|
+
"rhi.capture": {
|
|
3673
|
+
available: false,
|
|
3674
|
+
realm: "host",
|
|
3675
|
+
reason: "static-dist-host-does-not-install-dev-capture"
|
|
3676
|
+
}
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
};
|
|
3951
3680
|
} catch (cause) {
|
|
3952
3681
|
return { ok: false, error: commandError(cause, "preview-server-failed") };
|
|
3953
3682
|
}
|
|
@@ -3997,6 +3726,7 @@ var init_commands = __esm({
|
|
|
3997
3726
|
init_dist();
|
|
3998
3727
|
init_host();
|
|
3999
3728
|
init_project();
|
|
3729
|
+
init_types();
|
|
4000
3730
|
init_assets();
|
|
4001
3731
|
init_bootstrap_commands();
|
|
4002
3732
|
init_plugin_authoring();
|
|
@@ -4391,7 +4121,7 @@ function hasStaticToolDeclarations(entry) {
|
|
|
4391
4121
|
return Array.isArray(Reflect.get(entry.config, "tools"));
|
|
4392
4122
|
}
|
|
4393
4123
|
async function createViteModuleLoader(root) {
|
|
4394
|
-
const server = await createServer({
|
|
4124
|
+
const server = await createServer$2({
|
|
4395
4125
|
root,
|
|
4396
4126
|
appType: "custom",
|
|
4397
4127
|
configFile: false,
|
|
@@ -4773,9 +4503,11 @@ function createAdmissionReport(recipe, samples, thresholds = DEFAULT_ADMISSION_T
|
|
|
4773
4503
|
async function runBenchmarkAdmission(options) {
|
|
4774
4504
|
const sampleCount = options.thresholds?.sampleCountPerPhase ?? 30;
|
|
4775
4505
|
const samples = [];
|
|
4776
|
-
|
|
4506
|
+
const phases = ["cold", "warm"];
|
|
4507
|
+
const modes = ["private", "service"];
|
|
4508
|
+
for (const phase of phases) {
|
|
4777
4509
|
for (let index = 0; index < sampleCount; index += 1) {
|
|
4778
|
-
for (const mode of
|
|
4510
|
+
for (const mode of modes) {
|
|
4779
4511
|
const measurement = await options.measure(mode, phase, index);
|
|
4780
4512
|
samples.push({
|
|
4781
4513
|
mode,
|
|
@@ -4882,7 +4614,7 @@ function reply(response, status, payload) {
|
|
|
4882
4614
|
async function createCarrierProviderService(options) {
|
|
4883
4615
|
const host = options.host ?? "127.0.0.1";
|
|
4884
4616
|
const bearerToken = options.machine.offer.bearerToken;
|
|
4885
|
-
const server = createServer
|
|
4617
|
+
const server = createServer(async (request, response) => {
|
|
4886
4618
|
if (request.method !== "POST" || !request.url?.startsWith("/carrier/")) {
|
|
4887
4619
|
reply(
|
|
4888
4620
|
response,
|
|
@@ -5318,7 +5050,7 @@ function projectUri(projectRoot, path) {
|
|
|
5318
5050
|
return relative(projectRoot, path).split(sep).join("/");
|
|
5319
5051
|
}
|
|
5320
5052
|
async function allocateLoopbackPort() {
|
|
5321
|
-
const probe = createServer$
|
|
5053
|
+
const probe = createServer$1();
|
|
5322
5054
|
try {
|
|
5323
5055
|
await new Promise((resolve16, reject) => {
|
|
5324
5056
|
const onError = (error) => {
|
|
@@ -5497,7 +5229,7 @@ async function runBrowserPreviewHost(projectRoot, recipe, snapshot, runId, signa
|
|
|
5497
5229
|
let server;
|
|
5498
5230
|
try {
|
|
5499
5231
|
const port = await allocateLoopbackPort();
|
|
5500
|
-
server = await createServer({
|
|
5232
|
+
server = await createServer$2({
|
|
5501
5233
|
...config,
|
|
5502
5234
|
cacheDir,
|
|
5503
5235
|
logLevel: "silent",
|
|
@@ -5619,9 +5351,7 @@ async function runBrowserPreviewHost(projectRoot, recipe, snapshot, runId, signa
|
|
|
5619
5351
|
);
|
|
5620
5352
|
});
|
|
5621
5353
|
await Promise.all(responseDiagnostics);
|
|
5622
|
-
if (!captured.ok)
|
|
5623
|
-
return browserFailure("capture-run", captured.error, pageErrors);
|
|
5624
|
-
}
|
|
5354
|
+
if (!captured.ok) return browserFailure("capture-run", captured.error, pageErrors);
|
|
5625
5355
|
if (pageErrors.length > 0)
|
|
5626
5356
|
return browserFailure("capture-page-runtime", pageErrors[0], pageErrors);
|
|
5627
5357
|
const capturePng = await page.screenshot({ type: "png" });
|
|
@@ -5962,7 +5692,7 @@ function isAuthorized(request, bearerToken) {
|
|
|
5962
5692
|
async function createAuthenticatedLoopbackService(options) {
|
|
5963
5693
|
if (options.bearerToken.length < 8) throw new TypeError("service bearer token is too short");
|
|
5964
5694
|
const host = options.host ?? "127.0.0.1";
|
|
5965
|
-
const server = createServer
|
|
5695
|
+
const server = createServer(async (request, response) => {
|
|
5966
5696
|
if (request.method !== "POST" || request.url !== "/run") {
|
|
5967
5697
|
reply2(response, 404, { error: "service route not found" });
|
|
5968
5698
|
return;
|
|
@@ -6025,6 +5755,9 @@ async function createAuthenticatedLoopbackService(options) {
|
|
|
6025
5755
|
};
|
|
6026
5756
|
}
|
|
6027
5757
|
|
|
6028
|
-
|
|
5758
|
+
// src/index.ts
|
|
5759
|
+
init_types();
|
|
5760
|
+
|
|
5761
|
+
export { DEFAULT_ADMISSION_THRESHOLDS, RHI_DEBUG_OPERATION_MANIFEST, analyzePreviewArtifacts, assetAddCommand, assetInspectCommand, assetListCommand, assetVerifyCommand, bootstrapRealm, buildCommand, createAdmissionReport, createAuthenticatedLoopbackService, createAuthorContribution, createBuildContribution, createCarrierProvider, createCarrierProviderService, createCarrierRendezvous, createCliRhiDebugOperationContext, createDefaultContributions, createDevkitToolRuntime, createDomainPreviewContributions, createInitPlan, createMigrationRoster, createOfflineAnalysisContribution, createPreviewContribution, createPreviewContributions, createPreviewToolRuntime, createResourceProbe, createRhiDebugOperationContext, createServiceCache, createServiceExecutor, createToolClient, describeTool, devCommand, discoverRhiDebugOperations, doctorCommand, initCommand, listTools, materializeToolCatalog, newCommand, packageCommand, pluginInstallCommand, pluginUninstallCommand, previewCommand, readProjectFacts, rebuildToolCatalog, recoverRhiDebugError, renderRhiDebugHelp, resolveMigration, resolveProjectPort, resolveRealmCapability, runBenchmarkAdmission, runCarrierPreviewRoute, runGenericTool, runLibraryTool, runNamedTool, runPreviewHost, runPrivateTool, runRhiDebugCommand, runRhiDebugOperation, sdkInstallCommand, shaderCheckCommand, skillInstallCommand, skillVerifyCommand, summarizeBenchmarkSamples, testCommand, verifyDist, writeDistManifest };
|
|
6029
5762
|
//# sourceMappingURL=index.mjs.map
|
|
6030
5763
|
//# sourceMappingURL=index.mjs.map
|