@helix3/helix-cli 0.1.18-helix3.308 → 0.1.18-helix3.310
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/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/init.js +136 -29
- package/dist/init.js.map +1 -1
- package/dist/lib.d.ts +7 -3
- package/dist/lib.js +72 -23
- package/dist/lib.js.map +1 -1
- package/dist/screenshot/captureScreenshots.d.ts +7 -0
- package/dist/screenshot/captureScreenshots.js +70 -7
- package/dist/screenshot/captureScreenshots.js.map +1 -1
- package/dist/screenshot/publishThumbnail.d.ts +4 -0
- package/dist/screenshot/publishThumbnail.js +56 -0
- package/dist/screenshot/publishThumbnail.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_abs.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_expression.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_jbeam.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_materials.cpython-312.pyc +0 -0
package/dist/init.js
CHANGED
|
@@ -387,6 +387,7 @@ function indexHtml(title) {
|
|
|
387
387
|
background: #14161a; color: #cdd6e0; font: 13px/1.5 ui-monospace, monospace;
|
|
388
388
|
opacity: 1; transition: opacity 0.4s ease;
|
|
389
389
|
}
|
|
390
|
+
html[data-helix-hosted-loading] #loading { display: none; }
|
|
390
391
|
#loading.done { opacity: 0; pointer-events: none; }
|
|
391
392
|
#loading .card { width: min(360px, 76vw); text-align: center; }
|
|
392
393
|
#loading .eyebrow { font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: #6cc7ff; opacity: 0.75; }
|
|
@@ -402,6 +403,12 @@ function indexHtml(title) {
|
|
|
402
403
|
</style>
|
|
403
404
|
</head>
|
|
404
405
|
<body>
|
|
406
|
+
<script>
|
|
407
|
+
// The host owns the overlay only when it explicitly asks and this is an iframe.
|
|
408
|
+
if (window.parent !== window && new URLSearchParams(location.search).get('helixHostedLoading') === '1') {
|
|
409
|
+
document.documentElement.setAttribute('data-helix-hosted-loading', '');
|
|
410
|
+
}
|
|
411
|
+
</script>
|
|
405
412
|
<div id="loading">
|
|
406
413
|
<div class="card">
|
|
407
414
|
<div class="eyebrow">HELIX Instant</div>
|
|
@@ -417,8 +424,8 @@ function indexHtml(title) {
|
|
|
417
424
|
</html>
|
|
418
425
|
`;
|
|
419
426
|
}
|
|
420
|
-
const LOADING_TS = `//
|
|
421
|
-
//
|
|
427
|
+
const LOADING_TS = `// Standalone owns the HTML overlay; the hosted shell owns it with ?helixHostedLoading=1.
|
|
428
|
+
// Readiness means the first rendered frame, not the SDK handshake or an asset manager batch.
|
|
422
429
|
import * as THREE from 'three';
|
|
423
430
|
|
|
424
431
|
export type LoadingScreen = {
|
|
@@ -432,47 +439,129 @@ export function createLoadingScreen(): LoadingScreen {
|
|
|
432
439
|
const root = document.getElementById('loading');
|
|
433
440
|
const bar = document.getElementById('bar');
|
|
434
441
|
const text = document.getElementById('loading-text');
|
|
442
|
+
const hosted = window.parent !== window && new URLSearchParams(location.search).get('helixHostedLoading') === '1';
|
|
443
|
+
let parentOrigin = '*';
|
|
444
|
+
try {
|
|
445
|
+
const origin = new URL(document.referrer).origin;
|
|
446
|
+
if (origin !== 'null') parentOrigin = origin;
|
|
447
|
+
} catch { /* An opaque or absent referrer has no target origin; the shell validates our frame. */ }
|
|
435
448
|
let extraTotal = 0;
|
|
436
449
|
let extraDone = 0;
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
const
|
|
442
|
-
if (
|
|
443
|
-
|
|
444
|
-
bar.style.width = \`\${Math.min(100, Math.round((at / all) * 100))}%\`;
|
|
450
|
+
let assetsTotal = 0;
|
|
451
|
+
let assetsDone = 0;
|
|
452
|
+
let fraction = 0;
|
|
453
|
+
const progress = () => {
|
|
454
|
+
const total = assetsTotal + extraTotal;
|
|
455
|
+
if (total > 0) fraction = Math.max(fraction, Math.min(1, (assetsDone + extraDone) / total));
|
|
456
|
+
return { loaded: fraction * total, total };
|
|
445
457
|
};
|
|
458
|
+
let state: 'loading' | 'ready' | 'error' = 'loading';
|
|
459
|
+
let label = 'Starting…';
|
|
460
|
+
const manager = THREE.DefaultLoadingManager;
|
|
461
|
+
const previousProgress = manager.onProgress;
|
|
446
462
|
|
|
447
|
-
|
|
448
|
-
if (
|
|
449
|
-
|
|
463
|
+
const report = (error?: string) => {
|
|
464
|
+
if (!hosted) return;
|
|
465
|
+
const { total } = progress();
|
|
466
|
+
window.parent.postMessage({
|
|
467
|
+
type: 'helix:loading', state, label: label.slice(0, 160),
|
|
468
|
+
...(total > 0 ? { loaded: fraction, total: 1 } : {}),
|
|
469
|
+
...(error !== undefined ? { error: error.slice(0, 2000) } : {}),
|
|
470
|
+
}, parentOrigin);
|
|
471
|
+
};
|
|
472
|
+
const render = () => {
|
|
473
|
+
if (state !== 'loading') return;
|
|
474
|
+
const { total } = progress();
|
|
475
|
+
if (text) text.textContent = label;
|
|
476
|
+
if (root && bar && total > 0) {
|
|
477
|
+
root.classList.add('determinate');
|
|
478
|
+
bar.style.width = \`\${Math.min(100, Math.round(fraction * 100))}%\`;
|
|
479
|
+
}
|
|
480
|
+
report();
|
|
450
481
|
};
|
|
482
|
+
const fail = (message: string) => {
|
|
483
|
+
if (state !== 'loading') return;
|
|
484
|
+
const details = message || 'World startup failed';
|
|
485
|
+
state = 'error';
|
|
486
|
+
label = details;
|
|
487
|
+
root?.classList.add('error');
|
|
488
|
+
if (text) text.textContent = details;
|
|
489
|
+
report(details);
|
|
490
|
+
};
|
|
491
|
+
const onProgress: NonNullable<typeof manager.onProgress> = (url, loaded, total) => {
|
|
492
|
+
assetsDone = loaded;
|
|
493
|
+
assetsTotal = total;
|
|
494
|
+
label = 'Loading assets…';
|
|
495
|
+
render();
|
|
496
|
+
previousProgress?.call(manager, url, loaded, total);
|
|
497
|
+
};
|
|
498
|
+
manager.onProgress = onProgress;
|
|
499
|
+
// Claim the loading lifecycle synchronously, before Helix.init() sends its handshake.
|
|
500
|
+
report();
|
|
451
501
|
|
|
452
502
|
return {
|
|
453
|
-
task(
|
|
503
|
+
task(taskLabel) {
|
|
504
|
+
if (state !== 'loading') return () => {};
|
|
454
505
|
extraTotal += 1;
|
|
455
|
-
if (
|
|
506
|
+
if (taskLabel) label = taskLabel;
|
|
507
|
+
render();
|
|
456
508
|
let settled = false;
|
|
457
509
|
return () => {
|
|
458
|
-
if (settled) return;
|
|
510
|
+
if (settled || state !== 'loading') return;
|
|
459
511
|
settled = true;
|
|
460
512
|
extraDone += 1;
|
|
461
|
-
render(
|
|
513
|
+
render();
|
|
462
514
|
};
|
|
463
515
|
},
|
|
464
516
|
done() {
|
|
465
|
-
if (
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
517
|
+
if (state !== 'loading') return;
|
|
518
|
+
state = 'ready';
|
|
519
|
+
label = 'Ready';
|
|
520
|
+
if (text) text.textContent = label;
|
|
521
|
+
if (manager.onProgress === onProgress) manager.onProgress = previousProgress;
|
|
522
|
+
if (hosted) root?.remove();
|
|
523
|
+
else {
|
|
524
|
+
root?.classList.remove('working');
|
|
525
|
+
root?.classList.add('done');
|
|
526
|
+
setTimeout(() => root?.remove(), 500);
|
|
527
|
+
}
|
|
528
|
+
report();
|
|
473
529
|
},
|
|
530
|
+
error: fail,
|
|
474
531
|
};
|
|
475
532
|
}
|
|
533
|
+
|
|
534
|
+
// New facades expose honest initial equipped presentation readiness; older pinned facades
|
|
535
|
+
// have already assembled their compatible body by create(). Never wait on swap events.
|
|
536
|
+
export async function waitForInitialAvatar(character: unknown, loading: LoadingScreen, deadlineMs = 45_000): Promise<void> {
|
|
537
|
+
const facade = character as { initialAvatarReady?: PromiseLike<{ status: string }> };
|
|
538
|
+
if (!facade.initialAvatarReady || typeof facade.initialAvatarReady.then !== 'function') {
|
|
539
|
+
const finish = loading.task('Using compatible avatar…');
|
|
540
|
+
console.info('[HELIX] This character module uses its assembled compatible avatar; equipped-avatar readiness is unavailable.');
|
|
541
|
+
finish();
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
const finish = loading.task('Loading your avatar…');
|
|
545
|
+
let timeout: ReturnType<typeof setTimeout> | undefined;
|
|
546
|
+
try {
|
|
547
|
+
const result = await Promise.race([
|
|
548
|
+
facade.initialAvatarReady,
|
|
549
|
+
new Promise<never>((_, reject) => {
|
|
550
|
+
timeout = setTimeout(() => reject(new Error('Your avatar did not finish loading. Try again.')), deadlineMs);
|
|
551
|
+
}),
|
|
552
|
+
]);
|
|
553
|
+
if (!result || typeof result !== 'object') throw new Error('Your avatar reported an invalid readiness state. Try again.');
|
|
554
|
+
if (result.status === 'failed' || result.status === 'disposed') throw new Error('Your avatar could not be prepared. Try again.');
|
|
555
|
+
if (result.status !== 'ready' && result.status !== 'fallback') throw new Error('Your avatar reported an invalid readiness state. Try again.');
|
|
556
|
+
if (result.status === 'fallback') {
|
|
557
|
+
loading.task('Using compatible avatar…')();
|
|
558
|
+
console.info('[HELIX] The character module recovered a usable fallback avatar.');
|
|
559
|
+
}
|
|
560
|
+
finish();
|
|
561
|
+
} finally {
|
|
562
|
+
if (timeout !== undefined) clearTimeout(timeout);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
476
565
|
`;
|
|
477
566
|
// The one line this scaffold is most careful about:
|
|
478
567
|
//
|
|
@@ -496,7 +585,7 @@ import {
|
|
|
496
585
|
import { world } from '@helix/engine-core/inspect';
|
|
497
586
|
import { screenshots } from '@helix/engine-core/screenshot';
|
|
498
587
|
import { SYSTEM_ASSET_BASE, TRANSCODER_PATH } from './helix.runtime';
|
|
499
|
-
import { createLoadingScreen } from './loading';
|
|
588
|
+
import { createLoadingScreen, waitForInitialAvatar } from './loading';
|
|
500
589
|
|
|
501
590
|
// ${title} — a HELIX Instant ${multiplayer ? 'multiplayer' : 'character'} world.
|
|
502
591
|
//
|
|
@@ -590,6 +679,7 @@ addEventListener('resize', () => {
|
|
|
590
679
|
});
|
|
591
680
|
|
|
592
681
|
async function main(): Promise<void> {
|
|
682
|
+
const finishStartup = loading.task('Preparing world…');
|
|
593
683
|
// RapierBody.create is a static async factory — the constructor is private.
|
|
594
684
|
const body = await RapierBody.create({ position: SPAWN });
|
|
595
685
|
body.addStaticCuboid({ x: 24, y: 0.5, z: 24 }, { x: 0, y: -0.5, z: 0 }); // floor, top at y=0
|
|
@@ -638,6 +728,13 @@ async function main(): Promise<void> {
|
|
|
638
728
|
},
|
|
639
729
|
});
|
|
640
730
|
|
|
731
|
+
// Keep rendering while the initial equipped avatar settles, and reveal only a frame
|
|
732
|
+
// rendered after readiness. The public Promise includes native fallback recovery.
|
|
733
|
+
let avatarBootReady = false;
|
|
734
|
+
void waitForInitialAvatar(character, loading).then(() => { avatarBootReady = true; }).catch((error: unknown) => {
|
|
735
|
+
loading.error(error instanceof Error ? error.message : String(error));
|
|
736
|
+
});
|
|
737
|
+
|
|
641
738
|
// CharacterMultiplayer registers the platform actions (including \`emote\`) on the injected
|
|
642
739
|
// InputService. Format binding-aware onboarding only after those actions exist.
|
|
643
740
|
const desktopHint = (captured: boolean): string => {
|
|
@@ -683,8 +780,9 @@ async function main(): Promise<void> {
|
|
|
683
780
|
character.update(dt);
|
|
684
781
|
if (body.position.y < -10) character.local.respawn(); // fell off the world
|
|
685
782
|
renderer.render(scene, camera);
|
|
686
|
-
if (firstFrame) {
|
|
783
|
+
if (firstFrame && avatarBootReady) {
|
|
687
784
|
firstFrame = false;
|
|
785
|
+
finishStartup();
|
|
688
786
|
loading.done();
|
|
689
787
|
}
|
|
690
788
|
hud.textContent = mobileControls.active
|
|
@@ -742,7 +840,7 @@ import { attachSceneVisuals, sceneVisualsConfig } from '@helix/scene/visual';
|
|
|
742
840
|
import { world } from '@helix/engine-core/inspect';
|
|
743
841
|
import { screenshots } from '@helix/engine-core/screenshot';
|
|
744
842
|
import { SYSTEM_ASSET_BASE, TRANSCODER_PATH } from './helix.runtime';
|
|
745
|
-
import { createLoadingScreen } from './loading';
|
|
843
|
+
import { createLoadingScreen, waitForInitialAvatar } from './loading';
|
|
746
844
|
|
|
747
845
|
// ${title} — a HELIX Instant SCENE world. Its ENVIRONMENT is a published HELIX Scene v2 document
|
|
748
846
|
// streamed by @helix/scene and lit by @helix/visual's runtime: geometry, materials, authored lights,
|
|
@@ -818,6 +916,7 @@ addEventListener('resize', () => {
|
|
|
818
916
|
});
|
|
819
917
|
|
|
820
918
|
async function main(): Promise<void> {
|
|
919
|
+
const finishStartup = loading.task('Preparing world…');
|
|
821
920
|
// Before the document: the shell's \`helix:init\` is where the platform API base comes from.
|
|
822
921
|
await Helix.init();
|
|
823
922
|
|
|
@@ -893,6 +992,13 @@ async function main(): Promise<void> {
|
|
|
893
992
|
},
|
|
894
993
|
});
|
|
895
994
|
|
|
995
|
+
// Keep rendering while the initial equipped avatar settles, and reveal only a frame
|
|
996
|
+
// rendered after readiness. The public Promise includes native fallback recovery.
|
|
997
|
+
let avatarBootReady = false;
|
|
998
|
+
void waitForInitialAvatar(character, loading).then(() => { avatarBootReady = true; }).catch((error: unknown) => {
|
|
999
|
+
loading.error(error instanceof Error ? error.message : String(error));
|
|
1000
|
+
});
|
|
1001
|
+
|
|
896
1002
|
const desktopHint = (captured: boolean): string => {
|
|
897
1003
|
const cameraHint = captured
|
|
898
1004
|
? 'Move mouse to look · Scroll to zoom'
|
|
@@ -933,8 +1039,9 @@ async function main(): Promise<void> {
|
|
|
933
1039
|
character.update(dt);
|
|
934
1040
|
if (body.position.y < -10) character.local.respawn(); // fell out of the scene
|
|
935
1041
|
visuals?.tick(dt); // the clock, the sun, the cadences — and the frame's own render
|
|
936
|
-
if (firstFrame) {
|
|
1042
|
+
if (firstFrame && avatarBootReady) {
|
|
937
1043
|
firstFrame = false;
|
|
1044
|
+
finishStartup();
|
|
938
1045
|
loading.done();
|
|
939
1046
|
}
|
|
940
1047
|
hud.textContent = mobileControls.active
|
package/dist/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4JA,0BAOC;AAyCD,8CAIC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
package/dist/lib.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { capturePublishThumbnail } from './screenshot/publishThumbnail';
|
|
2
|
+
export { WORLD_THUMBNAIL_PUBLICATION_VERSION } from './screenshot/publishThumbnail';
|
|
1
3
|
import { HelixApi, uploadToTicket } from './api';
|
|
2
4
|
export { createPlacementRequest, validatePlacementRequest, placementRequestBundleFile, writePlacementRequest, PLACEMENT_REQUEST_FILENAME } from './placementRequest';
|
|
3
5
|
import { loadVendoredValidator } from './ability';
|
|
@@ -117,7 +119,7 @@ export type PublishResult = {
|
|
|
117
119
|
worldId: string;
|
|
118
120
|
hasCustomThumbnail: boolean;
|
|
119
121
|
thumbnailUrl: string | null;
|
|
120
|
-
thumbnailSource: 'option' | 'bundle' | 'existing' | 'generated';
|
|
122
|
+
thumbnailSource: 'option' | 'bundle' | 'existing' | 'capture' | 'generated';
|
|
121
123
|
thumbnailWarning: string | null;
|
|
122
124
|
/** What happened on the opt-in source channel. Always present; `skipped` unless the creator asked. */
|
|
123
125
|
source: PublishSourceOutcome;
|
|
@@ -151,6 +153,8 @@ export type PublishWorldOptions = {
|
|
|
151
153
|
/** Explicit JSON worldId/placements mapping from normal reservation receipts. */
|
|
152
154
|
placementBindings?: string;
|
|
153
155
|
thumbnail?: string;
|
|
156
|
+
/** Mock-only seam for source tests; public CLI/MCP always use isolated capture. */
|
|
157
|
+
captureThumbnail?: typeof capturePublishThumbnail;
|
|
154
158
|
/**
|
|
155
159
|
* Catalog description. Sent as a separate PATCH because the manifest schema cannot carry it —
|
|
156
160
|
* `@hypersoniclabs/helix-manifest` is `additionalProperties: false` at every version, so a
|
|
@@ -162,8 +166,8 @@ export type PublishWorldOptions = {
|
|
|
162
166
|
/**
|
|
163
167
|
* Opt-in, OFF BY DEFAULT (CH-1457 spec §9.1). Also upload this project's
|
|
164
168
|
* source, through a separate private channel, so the world can be opened and
|
|
165
|
-
* edited on the website later.
|
|
166
|
-
*
|
|
169
|
+
* edited on the website later. This flag does not alter the playable Build
|
|
170
|
+
* upload or its required thumbnail; source remains a separate private channel.
|
|
167
171
|
*/
|
|
168
172
|
uploadSource?: boolean;
|
|
169
173
|
/**
|
package/dist/lib.js
CHANGED
|
@@ -38,12 +38,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
38
38
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
39
39
|
};
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
exports.
|
|
42
|
-
exports.
|
|
43
|
-
exports.
|
|
44
|
-
exports.
|
|
45
|
-
exports.
|
|
46
|
-
exports.DEFAULT_HLOD_REFINEMENT_SETTINGS = exports.bakeSceneHlodRefinements = exports.DEFAULT_COMPLETE_HLOD_SETTINGS = exports.bakeCompleteSceneHlod = exports.writeSharedHlodMaterialGlb = exports.writeHlodCellGlb = exports.bakeSharedHlodAtlas = exports.planSharedHlodAtlas = exports.approximateHlodGeometry = exports.bakeHlodSurface = exports.HLOD_BAKER_VERSION = exports.DEFAULT_HLOD_LAYER = exports.planSceneHlod = exports.tagSceneHlod = exports.inspectSceneHlod = exports.bakeSceneHlod = exports.attachFoliageLods = exports.bakeFoliageLods = exports.replaceAvatarMesh = exports.DOCTOR_REPORT_SCHEMA = exports.findUProject = exports.locateEditorCmd = exports.runUnrealDoctor = exports.TOOLCHAIN_PACKAGES = exports.productsWorldPath = exports.CREATOR_WORLDS_PATH = exports.PRODUCTS_PATH = exports.ITEM_DISTRIBUTIONS_CREATOR_PATH = exports.ITEM_DISTRIBUTIONS_PATH = exports.achievementsWorldPath = exports.ITEM_PUBLISH_QUOTE_PATH = exports.ITEM_UPLOAD_PATH = exports.SERVER_CREATION_PERMISSIONS = exports.WORLD_DESCRIPTION_MAX = exports.WORLD_METRICS_UNSUPPORTED = exports.BASELINE_FILENAME = exports.anchorOf = exports.parseBaseline = exports.buildBaseline = exports.applyBaseline = exports.canonicalizeSnapshot = exports.detectNpcWiring = exports.detectInspectWiring = exports.resolveFocus = exports.formatWorldFocus = exports.analyzeZones = exports.formatWorldDiff = void 0;
|
|
41
|
+
exports.MATERIAL_AUTO_REPLACE_CONFIDENCE = exports.HELIX_OFFICIAL_MATERIAL_SUBSET = exports.compileContinuumScenePackage = exports.CONTINUUM_SCENE_DOCUMENT_MEDIA_TYPE = exports.compileSceneElementsBundle = exports.compileSceneElements = exports.cs2 = exports.terrain = exports.labelModuleValidationErrors = exports.updateInteractable = exports.subtractInteractableContribution = exports.parseInteractablePosition = exports.namespaceInteractableFragment = exports.moduleInteractableFragment = exports.instanceOrdinalOf = exports.interactableModuleId = exports.composeInteractableManifest = exports.composeInteractableModuleManifest = exports.addInteractable = exports.frozenBuildArtifactKey = exports.freezeBuildDraft = exports.createPrivateBuildDraft = exports.PRIVATE_BUILD_DRAFT_SCHEMA = exports.checkPackageBundle = exports.MULTIPLAYER_CONFIG_FILENAME = exports.multiplayerConfigBundleFile = exports.PLATFORM_THREE_VERSION = exports.tiledTerrainBakedLightingWarning = exports.checkBundle = exports.validateDeviceProject = exports.testDeviceProject = exports.readDeviceGlbNodeNames = exports.createDeviceProject = exports.DEVICE_FILENAME = exports.placementsContinuum = exports.placementsBundle = exports.inspectPlacementsBake = exports.readPlacementsBake = exports.attachTreeImpostors = exports.bakeTreeImpostors = exports.bakePlacements = exports.uploadToTicket = exports.HelixApi = exports.ApiError = exports.PLACEMENT_REQUEST_FILENAME = exports.writePlacementRequest = exports.placementRequestBundleFile = exports.validatePlacementRequest = exports.createPlacementRequest = exports.WORLD_THUMBNAIL_PUBLICATION_VERSION = void 0;
|
|
42
|
+
exports.ITEM_DISTRIBUTION_CHANNELS = exports.DISTRIBUTION_KEY_PATTERN = exports.UPLOADABLE_ITEM_KINDS = exports.thumbnailContentTypeFromExtension = exports.renderCcSlotTable = exports.renderCcGenderList = exports.parseTags = exports.parseGenders = exports.parseJsonOrFile = exports.parseJsonObjectOrFile = exports.parseJsonArrayOrFile = exports.normalizeItemKind = exports.meshSizeWarning = exports.meshContentTypeFromExtension = exports.isUploadableItemKind = exports.isMeshlessItem = exports.describeUploadableItemKinds = exports.CLIP_SET_SLOT_TYPES = exports.isCcWearableSlot = exports.isCcGender = exports.ccSlotIsRequiredForKind = exports.ccSlotIsAllowedForKind = exports.ccGendersAreRequiredForKind = exports.ccGendersAreAllowedForKind = exports.CC_WEARABLE_SLOT_GROUPS = exports.CC_WEARABLE_SLOTS = exports.CC_GENDERS = exports.buildItemPayload = exports.assertLooksLikeGlb = exports.assertCcSlot = exports.assertCcGenders = exports.SOURCE_MAX_BYTES = exports.SOURCE_HARD_EXCLUDES = exports.SOURCE_CONTENT_TYPE = exports.SOURCE_ARCHIVE_FILENAME = exports.parseGitignore = exports.isSourceExcluded = exports.formatArchiveSize = exports.createSourceArchive = exports.collectSourceFiles = exports.formatScenePerformanceReport = exports.analyzeScenePerformance = exports.importSourceSceneMap = exports.SOURCE_SCENE_IMPORT_BUDGETS = exports.NATIVE_SCENE_CONVERSION_CONFIDENCE = exports.matchCanonicalMaterial = exports.createSharedMaterialBinding = exports.buildMaterialPackageRecipe = exports.buildMaterialBulkRecipe = exports.MATERIAL_REVIEW_CONFIDENCE = void 0;
|
|
43
|
+
exports.assessVaultAssets = exports.assessThreeCurrency = exports.assessPlatformDelivery = exports.assessInteractables = exports.WORLD_MANIFEST_LOCATIONS = exports.MODULES_DIR = exports.LOCKFILE = exports.INSTALLED_INDEX = exports.installWorld = exports.resolvePins = exports.validateAssetPackConstraints = exports.normalizePinRange = exports.loadInstalledIndexValidator = exports.loadVendoredValidator = exports.installLocalAbility = exports.checkAbilityBundle = exports.productTypeGrantsItem = exports.isProductKey = exports.buildProductUpdate = exports.buildProductRegistration = exports.WORLD_PRODUCT_TYPES = exports.PRODUCT_TITLE_MAX = exports.PRODUCT_KEY_PATTERN = exports.PRODUCT_KEY_MAX = exports.PRODUCT_DESCRIPTION_MAX = exports.MAX_PASS_DURATION_SECONDS = exports.MAX_GRANT_ITEM_QUANTITY = exports.MAX_GRANT_EFFECTS = exports.MAX_GRANT_CURRENCY_AMOUNT = exports.GRANT_CODE_PATTERN = exports.GRANT_CODE_MAX = exports.resolveUnlockMode = exports.isAchievementKey = exports.iconContentTypeFromExtension = exports.formatAchievementCriteria = exports.buildAchievementUpdate = exports.buildAchievementRegistration = exports.buildAchievementCriteria = exports.DATA_STORE_CRITERIA_KEY_TEMPLATES = exports.ACHIEVEMENT_UNLOCK_MODES = exports.ACHIEVEMENT_TROPHY_MAX_BYTES = exports.ACHIEVEMENT_KEY_PATTERN = exports.ACHIEVEMENT_ICON_MAX_BYTES = exports.ACHIEVEMENT_CRITERIA_SIGNALS = exports.ACHIEVEMENT_CRITERIA_OPS = exports.ACHIEVEMENT_CRITERIA_METRICS = exports.editionFields = exports.buildItemDistributionUpdate = exports.buildItemDistribution = exports.ITEM_EDITION_MODES = void 0;
|
|
44
|
+
exports.getVaultAssetUsage = exports.getVaultAsset = exports.getStandaloneAssetGenerationJob = exports.getDreamerAssetGenerationJob = exports.generateStandaloneAsset = exports.generateImage = exports.generateAudio = exports.generateAndPublishAssetFromReference = exports.generateAndPublishAsset = exports.formatStrandedJob = exports.extensionFor = exports.describeGateAdvance = exports.approveDreamerGate = exports.DEFAULT_MOUNT_PREFIX = exports.formatSubPathResult = exports.verifySubPath = exports.roundLix = exports.receiptLix = exports.formatWaitState = exports.formatReceipt = exports.formatLix = exports.formatQuote = exports.formatBalance = exports.normalizeQuote = exports.quoteGeneration = exports.formatJobs = exports.listJobs = exports.getLixBalance = exports.TICK_NODE_CEILING = exports.renderRealizabilityRefusal = exports.registryRealizabilityDeps = exports.checkRealizability = exports.initAbilityTemplate = exports.slugify = exports.initTemplate = exports.defaultClientTokenName = exports.browserLogin = exports.jwtExpiresAtIso = exports.clearCredentials = exports.saveCredentials = exports.loadCredentials = exports.HELIX_SCOPE = exports.HELIX_ENV = exports.DEFAULT_WEB_URL = exports.DEFAULT_API_URL = exports.credsEnvMismatchWarning = exports.apiUrlMatchesEnv = exports.ADVISORY_SYSTEMS = exports.assessWorldCurrency = exports.assessWeaponPins = void 0;
|
|
45
|
+
exports.DEFAULT_REPORT = exports.formatWorldInspection = exports.sortFindings = exports.analyzeWorld = exports.validateUnrealProject = exports.packageUnrealProject = exports.initUnrealManifest = exports.HELIX_UNREAL_ENGINE_VERSION = exports.HELIX_UNREAL_CONTRACT_VERSION = exports.formatUnrealValidationReport = exports.uploadArtifact = exports.resolveWorldId = exports.renderPublishFailure = exports.publishUnrealBuild = exports.assertReceipt = exports.assertCreateResponseMatchesPlan = exports.assertClientDeliveryMatchesPlan = exports.verifyUnrealCandidate = exports.UnrealCandidateError = exports.planSharedRuntimePublish = exports.defaultIdempotencyKey = exports.candidateArtifactDigest = exports.auditCookScope = exports.clearMaterialPinCache = exports.platformMaterialTag = exports.parseVaultMaterialSearch = exports.parseContinuumCurrentVersion = exports.materialContinuumIdentity = exports.matchMaterialResolution = exports.materialResolutionOptions = exports.materialDefaultResolutionKey = exports.DEFAULT_RESOLUTION_KEY = exports.VAULT_ASSET_KINDS = exports.UnavailableCapabilityError = exports.updateVaultAssetMetadata = exports.startStandaloneAssetGeneration = exports.startDreamerAssetGenerationFromReference = exports.startDreamerAssetGeneration = exports.searchVaultAssets = exports.StrandedJobError = exports.saveGeneratedAsset = exports.reviseDreamerGate = exports.retryDreamerJob = exports.resumeAndPublishAsset = exports.resolveMaterial = exports.MATERIAL_RENDITION_SELECTIONS = exports.listMaterials = exports.listDreamerVoices = exports.installVaultAsset = exports.getVaultAssetVersions = void 0;
|
|
46
|
+
exports.DEFAULT_HLOD_REFINEMENT_SETTINGS = exports.bakeSceneHlodRefinements = exports.DEFAULT_COMPLETE_HLOD_SETTINGS = exports.bakeCompleteSceneHlod = exports.writeSharedHlodMaterialGlb = exports.writeHlodCellGlb = exports.bakeSharedHlodAtlas = exports.planSharedHlodAtlas = exports.approximateHlodGeometry = exports.bakeHlodSurface = exports.HLOD_BAKER_VERSION = exports.DEFAULT_HLOD_LAYER = exports.planSceneHlod = exports.tagSceneHlod = exports.inspectSceneHlod = exports.bakeSceneHlod = exports.attachFoliageLods = exports.bakeFoliageLods = exports.replaceAvatarMesh = exports.DOCTOR_REPORT_SCHEMA = exports.findUProject = exports.locateEditorCmd = exports.runUnrealDoctor = exports.TOOLCHAIN_PACKAGES = exports.productsWorldPath = exports.CREATOR_WORLDS_PATH = exports.PRODUCTS_PATH = exports.ITEM_DISTRIBUTIONS_CREATOR_PATH = exports.ITEM_DISTRIBUTIONS_PATH = exports.achievementsWorldPath = exports.ITEM_PUBLISH_QUOTE_PATH = exports.ITEM_UPLOAD_PATH = exports.SERVER_CREATION_PERMISSIONS = exports.WORLD_DESCRIPTION_MAX = exports.WORLD_METRICS_UNSUPPORTED = exports.BASELINE_FILENAME = exports.anchorOf = exports.parseBaseline = exports.buildBaseline = exports.applyBaseline = exports.canonicalizeSnapshot = exports.detectNpcWiring = exports.detectInspectWiring = exports.resolveFocus = exports.formatWorldFocus = exports.analyzeZones = exports.formatWorldDiff = exports.diffWorldSnapshots = void 0;
|
|
47
47
|
exports.importCharacter = importCharacter;
|
|
48
48
|
exports.captureScreenshots = captureScreenshots;
|
|
49
49
|
exports.encodeImagePreview = encodeImagePreview;
|
|
@@ -102,9 +102,14 @@ exports.cliVersion = cliVersion;
|
|
|
102
102
|
exports.latestOnNpm = latestOnNpm;
|
|
103
103
|
exports.installHint = installHint;
|
|
104
104
|
exports.checkForUpdates = checkForUpdates;
|
|
105
|
+
const helix_manifest_1 = require("@hypersoniclabs/helix-manifest");
|
|
106
|
+
const publishThumbnail_1 = require("./screenshot/publishThumbnail");
|
|
107
|
+
var publishThumbnail_2 = require("./screenshot/publishThumbnail");
|
|
108
|
+
Object.defineProperty(exports, "WORLD_THUMBNAIL_PUBLICATION_VERSION", { enumerable: true, get: function () { return publishThumbnail_2.WORLD_THUMBNAIL_PUBLICATION_VERSION; } });
|
|
105
109
|
const baseColorGuard_1 = require("./character/baseColorGuard");
|
|
106
110
|
const node_fs_1 = require("node:fs");
|
|
107
111
|
const node_crypto_1 = require("node:crypto");
|
|
112
|
+
const node_os_1 = require("node:os");
|
|
108
113
|
const node_path_1 = require("node:path");
|
|
109
114
|
const api_1 = require("./api");
|
|
110
115
|
const placementRequest_1 = require("./placementRequest");
|
|
@@ -592,6 +597,57 @@ async function publishWorld(root, creds, onProgress = () => undefined, options =
|
|
|
592
597
|
if (placement && (!world || world.id !== placement.request.worldId)) {
|
|
593
598
|
throw new Error('Placement request must target the existing owned world; nothing was published');
|
|
594
599
|
}
|
|
600
|
+
// Resolve before capture, but capture/validate BEFORE any World/Build write.
|
|
601
|
+
const existingDetail = world ? await api.requestItem('GET', `/api/v1/instant-worlds/${manifest.slug}`) : null;
|
|
602
|
+
const requestedThumbnail = options.thumbnail ?? findBundleThumbnail(root);
|
|
603
|
+
bundle.files = bundle.files.filter(f => !/^helix\.thumbnail\.(auto|custom|required)\./.test(f.path));
|
|
604
|
+
let thumbnailSource = 'existing';
|
|
605
|
+
if (!existingDetail?.hasCustomThumbnail) {
|
|
606
|
+
let bytes;
|
|
607
|
+
let path;
|
|
608
|
+
if (requestedThumbnail) {
|
|
609
|
+
mediaContentTypeFromExtension(requestedThumbnail);
|
|
610
|
+
bytes = (0, node_fs_1.readFileSync)(requestedThumbnail);
|
|
611
|
+
// Consume the dedicated conventional cover once. Explicit selections may be
|
|
612
|
+
// runtime assets whose original paths must remain available to the World.
|
|
613
|
+
if (!options.thumbnail)
|
|
614
|
+
bundle.files = bundle.files.filter(f => (0, node_path_1.resolve)(f.absolutePath) !== (0, node_path_1.resolve)(requestedThumbnail));
|
|
615
|
+
path = `helix.thumbnail.custom${(0, node_path_1.extname)(requestedThumbnail).toLowerCase()}`;
|
|
616
|
+
thumbnailSource = options.thumbnail ? 'option' : 'bundle';
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
onProgress('Capturing publication thumbnail from the ready world');
|
|
620
|
+
const snapshot = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'helix-publish-bundle-'));
|
|
621
|
+
try {
|
|
622
|
+
// Capture precisely the filtered/generated bundle, and upload those same immutable bytes.
|
|
623
|
+
for (const file of bundle.files) {
|
|
624
|
+
file.content = file.content ?? (0, node_fs_1.readFileSync)(file.absolutePath);
|
|
625
|
+
file.size = file.content.byteLength;
|
|
626
|
+
const staged = (0, node_path_1.join)(snapshot, file.path);
|
|
627
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(staged), { recursive: true });
|
|
628
|
+
(0, node_fs_1.writeFileSync)(staged, file.content);
|
|
629
|
+
}
|
|
630
|
+
bytes = await (options.captureThumbnail ?? publishThumbnail_1.capturePublishThumbnail)(snapshot, manifest.entry, onProgress);
|
|
631
|
+
}
|
|
632
|
+
catch (err) {
|
|
633
|
+
throw new Error(`Automatic thumbnail capture failed; nothing was published: ${describeSourceFailure(err)}`);
|
|
634
|
+
}
|
|
635
|
+
finally {
|
|
636
|
+
(0, node_fs_1.rmSync)(snapshot, { recursive: true, force: true });
|
|
637
|
+
}
|
|
638
|
+
path = publishThumbnail_1.AUTO_THUMBNAIL_PATH;
|
|
639
|
+
thumbnailSource = 'capture';
|
|
640
|
+
}
|
|
641
|
+
assertMediaSizeOk(bytes.byteLength, 'thumbnail');
|
|
642
|
+
if (!bytes.byteLength)
|
|
643
|
+
throw new Error('Publication thumbnail is empty; nothing was published');
|
|
644
|
+
// Keep generated bytes in memory: source and bundle directories remain untouched.
|
|
645
|
+
bundle.files = bundle.files.filter(f => !/^helix\.thumbnail\.(auto|custom)\./.test(f.path));
|
|
646
|
+
bundle.files.push({ path, size: bytes.byteLength, absolutePath: '', content: bytes });
|
|
647
|
+
}
|
|
648
|
+
if (bundle.files.length > helix_manifest_1.BUNDLE_MAX_FILES || bundle.files.reduce((sum, f) => sum + f.size, 0) > helix_manifest_1.BUNDLE_MAX_TOTAL_BYTES) {
|
|
649
|
+
throw new Error('Bundle including publication thumbnail exceeds the file count or byte budget; nothing was published');
|
|
650
|
+
}
|
|
595
651
|
if (!world) {
|
|
596
652
|
onProgress(`Creating world "${manifest.title}" (${manifest.slug})`);
|
|
597
653
|
world = await api.requestItem('POST', '/api/v1/instant-worlds', {
|
|
@@ -621,6 +677,8 @@ async function publishWorld(root, creds, onProgress = () => undefined, options =
|
|
|
621
677
|
manifest,
|
|
622
678
|
files: buildFiles,
|
|
623
679
|
});
|
|
680
|
+
if (build.thumbnailAssignmentVersion !== 1)
|
|
681
|
+
throw new Error('Backend does not support atomic publication thumbnails. Build remains inactive; activate the backend fix before retrying.');
|
|
624
682
|
const declaredByPath = new Map(buildFiles.map((file) => [file.path, file]));
|
|
625
683
|
let done = 0;
|
|
626
684
|
const queue = [...build.uploads];
|
|
@@ -644,24 +702,15 @@ async function publishWorld(root, creds, onProgress = () => undefined, options =
|
|
|
644
702
|
onProgress('Finalizing');
|
|
645
703
|
await api.request('POST', `/api/v1/instant-worlds/${world.id}/builds/${build.buildId}/finalize`);
|
|
646
704
|
const detail = await api.requestItem('GET', `/api/v1/instant-worlds/${manifest.slug}`);
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
if (detail.hasCustomThumbnail) {
|
|
652
|
-
thumbnailSource = 'existing';
|
|
653
|
-
}
|
|
654
|
-
else if (requestedThumbnail) {
|
|
655
|
-
onProgress('Uploading world thumbnail');
|
|
656
|
-
settledDetail = await setWorldMediaWithApi(manifest.slug, requestedThumbnail, api, { kind: 'thumbnail', overwrite: false });
|
|
657
|
-
thumbnailSource = options.thumbnail ? 'option' : 'bundle';
|
|
705
|
+
if (detail.id !== world.id || detail.activeBuildId !== build.buildId)
|
|
706
|
+
throw new Error(`Build ${build.buildId} finalized, but another Build is now active; publication result is superseded. Inspect the World before retrying.`);
|
|
707
|
+
if (!detail.thumbnailUrl || detail.thumbnailUrl.startsWith('data:image/svg')) {
|
|
708
|
+
throw new Error(`Build ${build.buildId} was activated but its thumbnail is missing; publication is incomplete. Inspect this Build before retrying.`);
|
|
658
709
|
}
|
|
659
|
-
|
|
660
|
-
thumbnailSource = '
|
|
661
|
-
|
|
662
|
-
const thumbnailWarning =
|
|
663
|
-
? `No custom thumbnail was supplied. Capture one, then run: helix thumbnail set ${manifest.slug} <file>`
|
|
664
|
-
: null;
|
|
710
|
+
if (detail.hasCustomThumbnail && thumbnailSource === 'capture')
|
|
711
|
+
thumbnailSource = 'existing';
|
|
712
|
+
const settledDetail = detail;
|
|
713
|
+
const thumbnailWarning = null;
|
|
665
714
|
let source = { state: 'skipped' };
|
|
666
715
|
if (archive) {
|
|
667
716
|
onProgress(`Uploading source (${archive.files.length} files, ${(0, source_archive_1.formatArchiveSize)(archive.bytes.byteLength)})`);
|