@auraindustry/aurajs 0.1.1 → 0.1.5
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 +7 -0
- package/benchmarks/perf-thresholds.json +27 -0
- package/package.json +6 -1
- package/src/ai-guidance.mjs +302 -0
- package/src/asset-pack.mjs +2 -1
- package/src/authored-project.mjs +498 -2
- package/src/authored-runtime.mjs +14 -0
- package/src/bin-integrity.mjs +33 -26
- package/src/build-contract/capabilities.mjs +87 -1
- package/src/build-contract/constants.mjs +1 -0
- package/src/build-contract.mjs +2 -0
- package/src/bundler.mjs +143 -13
- package/src/cli.mjs +681 -13
- package/src/commands/packs.mjs +741 -0
- package/src/commands/project-authoring.mjs +128 -1
- package/src/conformance/cases/app-and-ui-runtime-cases.mjs +1 -2
- package/src/conformance/cases/core-runtime-cases.mjs +6 -2
- package/src/conformance/cases/scene3d-and-media-cases.mjs +238 -0
- package/src/conformance/cases/systems-and-gameplay-cases.mjs +1126 -10
- package/src/conformance-mobile.mjs +166 -0
- package/src/conformance.mjs +89 -30
- package/src/evidence-bundle.mjs +242 -0
- package/src/external-package-surface.mjs +1 -1
- package/src/headless-test/runtime-coordinator.mjs +186 -33
- package/src/headless-test.mjs +2 -0
- package/src/helpers/2d/index.mjs +183 -0
- package/src/helpers/index.mjs +26 -0
- package/src/helpers/starter-utils/adventure-objectives.js +102 -0
- package/src/helpers/starter-utils/adventure-world-2d.js +221 -0
- package/src/helpers/starter-utils/animation-2d.js +337 -0
- package/src/helpers/starter-utils/animation-packaging-2d.js +203 -0
- package/src/helpers/starter-utils/atlas-assets-2d.js +111 -0
- package/src/helpers/starter-utils/autoplay-debug-2d.js +215 -0
- package/src/helpers/starter-utils/avatar-3d.js +404 -0
- package/src/helpers/starter-utils/combat-feedback-2d.js +320 -0
- package/src/helpers/starter-utils/combat-runtime-2d.js +290 -0
- package/src/helpers/starter-utils/core.js +150 -0
- package/src/helpers/starter-utils/dialogue-2d.js +351 -0
- package/src/helpers/starter-utils/enemy-archetypes-2d.js +68 -0
- package/src/helpers/starter-utils/index.js +26 -0
- package/src/helpers/starter-utils/inventory-2d.js +268 -0
- package/src/helpers/starter-utils/journal-2d.js +267 -0
- package/src/helpers/starter-utils/platformer-3d.js +132 -0
- package/src/helpers/starter-utils/scene-audio-2d.js +236 -0
- package/src/helpers/starter-utils/streamed-world-2d.js +378 -0
- package/src/helpers/starter-utils/tilemap-nav-2d.js +499 -0
- package/src/helpers/starter-utils/tilemap-world-2d.js +205 -0
- package/src/helpers/starter-utils/triggers.js +662 -0
- package/src/helpers/starter-utils/tween-2d.js +615 -0
- package/src/helpers/starter-utils/wave-director.js +101 -0
- package/src/helpers/starter-utils/world-compositor-2d.js +253 -0
- package/src/helpers/starter-utils/world-persistence-2d.js +180 -0
- package/src/mobile/android/build.mjs +606 -0
- package/src/mobile/android/host-artifact.mjs +280 -0
- package/src/mobile/ios/build.mjs +1323 -0
- package/src/mobile/ios/host-artifact.mjs +819 -0
- package/src/mobile/shared/capabilities.mjs +174 -0
- package/src/package-integrity.mjs +18 -4
- package/src/packs/catalog.mjs +259 -0
- package/src/perf-benchmark-runner.mjs +17 -12
- package/src/perf-benchmark.mjs +408 -4
- package/src/publish-command.mjs +434 -17
- package/src/publish-validation.mjs +22 -11
- package/src/replay-runtime.mjs +257 -0
- package/src/scaffold/config.mjs +2 -0
- package/src/scaffold/fs.mjs +8 -1
- package/src/scaffold/project-docs.mjs +101 -41
- package/src/scaffold.mjs +4 -0
- package/src/session-runtime.mjs +4 -3
- package/src/web-conformance.mjs +0 -36
- package/templates/create/2d/src/runtime/app.js +4 -0
- package/templates/create/2d-adventure/config/gameplay/adventure.config.js +9 -6
- package/templates/create/2d-adventure/content/gameplay/dialogue.js +85 -0
- package/templates/create/2d-adventure/content/gameplay/world.js +32 -36
- package/templates/create/2d-adventure/content/gameplay/world.tilemap.json +273 -0
- package/templates/create/2d-adventure/docs/design/loop.md +4 -3
- package/templates/create/2d-adventure/prefabs/relic.prefab.js +10 -10
- package/templates/create/2d-adventure/prefabs/world.prefab.js +127 -74
- package/templates/create/2d-adventure/scenes/gameplay.scene.js +603 -112
- package/templates/create/2d-adventure/src/runtime/capabilities.js +16 -0
- package/templates/create/2d-adventure/ui/hud.screen.js +187 -4
- package/templates/create/2d-adventure/ui/journal.screen.js +183 -0
- package/templates/create/2d-survivor/src/runtime/app.js +4 -0
- package/templates/create/3d/scenes/gameplay.scene.js +30 -3
- package/templates/create/3d/src/runtime/app.js +4 -0
- package/templates/create/3d/src/runtime/capabilities.js +5 -0
- package/templates/create/3d/src/runtime/materials.js +10 -0
- package/templates/create/3d-adventure/scenes/gameplay.scene.js +30 -3
- package/templates/create/3d-adventure/src/runtime/capabilities.js +5 -0
- package/templates/create/3d-adventure/src/runtime/materials.js +11 -0
- package/templates/create/3d-collectathon/scenes/gameplay.scene.js +30 -3
- package/templates/create/3d-collectathon/src/runtime/app.js +4 -0
- package/templates/create/3d-collectathon/src/runtime/capabilities.js +5 -0
- package/templates/create/3d-collectathon/src/runtime/materials.js +10 -0
- package/templates/create/blank/assets/splash/aurajs-gg-wordmark.webp +0 -0
- package/templates/create/blank/assets/splash/bg.webp +0 -0
- package/templates/create/blank/assets/splash/boot-loop.wav +0 -0
- package/templates/create/blank/assets/splash/boot-sting.wav +0 -0
- package/templates/create/blank/assets/splash/logo-mascot-sheet.webp +0 -0
- package/templates/create/blank/assets/splash/logoholo.webp +0 -0
- package/templates/create/blank/src/main.js +5 -1
- package/templates/create/blank/src/runtime/splash.js +305 -0
- package/templates/create/local-multiplayer/scenes/gameplay.scene.js +186 -12
- package/templates/create/local-multiplayer/src/runtime/capabilities.js +8 -1
- package/templates/create/shared/assets/splash/aurajs-gg-wordmark.webp +0 -0
- package/templates/create/shared/assets/splash/bg.webp +0 -0
- package/templates/create/shared/assets/splash/boot-loop.wav +0 -0
- package/templates/create/shared/assets/splash/boot-sting.wav +0 -0
- package/templates/create/shared/assets/splash/logo-mascot-sheet.webp +0 -0
- package/templates/create/shared/assets/splash/logoholo.webp +0 -0
- package/templates/create/shared/src/runtime/splash.js +305 -0
- package/templates/create/shared/src/runtime/ui-forms.js +552 -0
- package/templates/create/shared/src/starter-utils/adventure-world-2d.js +221 -0
- package/templates/create/shared/src/starter-utils/animation-packaging-2d.js +203 -0
- package/templates/create/shared/src/starter-utils/atlas-assets-2d.js +111 -0
- package/templates/create/shared/src/starter-utils/autoplay-debug-2d.js +215 -0
- package/templates/create/shared/src/starter-utils/combat-runtime-2d.js +290 -0
- package/templates/create/shared/src/starter-utils/dialogue-2d.js +351 -0
- package/templates/create/shared/src/starter-utils/index.js +15 -1
- package/templates/create/shared/src/starter-utils/inventory-2d.js +268 -0
- package/templates/create/shared/src/starter-utils/journal-2d.js +267 -0
- package/templates/create/shared/src/starter-utils/scene-audio-2d.js +236 -0
- package/templates/create/shared/src/starter-utils/streamed-world-2d.js +378 -0
- package/templates/create/shared/src/starter-utils/tilemap-nav-2d.js +499 -0
- package/templates/create/shared/src/starter-utils/tilemap-world-2d.js +205 -0
- package/templates/create/shared/src/starter-utils/world-compositor-2d.js +253 -0
- package/templates/create/shared/src/starter-utils/world-persistence-2d.js +180 -0
- package/templates/create/video-cutscene/src/runtime/app.js +4 -0
- package/templates/create-bin/play.js +148 -7
- package/templates/skills/auramaxx/SKILL.md +46 -0
- package/templates/skills/auramaxx/project-requirements.md +68 -0
- package/templates/skills/auramaxx/starter-recipes.md +104 -0
- package/templates/skills/auramaxx/validation-checklist.md +49 -0
- package/templates/starter/assets/splash/aurajs-gg-wordmark.webp +0 -0
- package/templates/starter/assets/splash/bg.webp +0 -0
- package/templates/starter/assets/splash/boot-loop.wav +0 -0
- package/templates/starter/assets/splash/boot-sting.wav +0 -0
- package/templates/starter/assets/splash/logo-mascot-sheet.webp +0 -0
- package/templates/starter/assets/splash/logoholo.webp +0 -0
- package/templates/starter/src/main.js +4 -0
- package/templates/starter/src/runtime/splash.js +305 -0
- package/templates/skills/aurajs/SKILL.md +0 -96
- package/templates/skills/aurajs/api-contract-3d.md +0 -7
- package/templates/skills/aurajs/api-contract.md +0 -7
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { MOBILE_CAPABILITY_REPORT_SCHEMA } from '../../build-contract/constants.mjs';
|
|
2
|
+
|
|
3
|
+
export const MOBILE_BUILD_TARGETS = new Set(['android', 'ios', 'mobile']);
|
|
4
|
+
|
|
5
|
+
const MOBILE_UNSUPPORTED_API_RULES = Object.freeze([
|
|
6
|
+
Object.freeze({
|
|
7
|
+
api: 'aura.input.isKeyDown',
|
|
8
|
+
capability: 'keyboardInput',
|
|
9
|
+
reasonCode: 'mobile_keyboard_first_control_deferred',
|
|
10
|
+
}),
|
|
11
|
+
Object.freeze({
|
|
12
|
+
api: 'aura.input.isKeyPressed',
|
|
13
|
+
capability: 'keyboardInput',
|
|
14
|
+
reasonCode: 'mobile_keyboard_first_control_deferred',
|
|
15
|
+
}),
|
|
16
|
+
Object.freeze({
|
|
17
|
+
api: 'aura.input.isKeyReleased',
|
|
18
|
+
capability: 'keyboardInput',
|
|
19
|
+
reasonCode: 'mobile_keyboard_first_control_deferred',
|
|
20
|
+
}),
|
|
21
|
+
Object.freeze({
|
|
22
|
+
api: 'aura.input.pressed',
|
|
23
|
+
capability: 'keyboardInput',
|
|
24
|
+
reasonCode: 'mobile_keyboard_first_control_deferred',
|
|
25
|
+
}),
|
|
26
|
+
Object.freeze({
|
|
27
|
+
api: 'aura.input.justPressed',
|
|
28
|
+
capability: 'keyboardInput',
|
|
29
|
+
reasonCode: 'mobile_keyboard_first_control_deferred',
|
|
30
|
+
}),
|
|
31
|
+
Object.freeze({
|
|
32
|
+
api: 'aura.input.released',
|
|
33
|
+
capability: 'keyboardInput',
|
|
34
|
+
reasonCode: 'mobile_keyboard_first_control_deferred',
|
|
35
|
+
}),
|
|
36
|
+
Object.freeze({
|
|
37
|
+
api: 'aura.window.setCursorLocked',
|
|
38
|
+
capability: 'cursorLock',
|
|
39
|
+
reasonCode: 'mobile_cursor_lock_unsupported',
|
|
40
|
+
}),
|
|
41
|
+
Object.freeze({
|
|
42
|
+
api: 'aura.input.getMouseWheel',
|
|
43
|
+
capability: 'mouseWheel',
|
|
44
|
+
reasonCode: 'mobile_mouse_wheel_unsupported',
|
|
45
|
+
}),
|
|
46
|
+
Object.freeze({
|
|
47
|
+
api: 'aura.window.setSize',
|
|
48
|
+
capability: 'windowManagement',
|
|
49
|
+
reasonCode: 'mobile_window_management_unsupported',
|
|
50
|
+
}),
|
|
51
|
+
Object.freeze({
|
|
52
|
+
api: 'aura.window.setFullscreen',
|
|
53
|
+
capability: 'windowManagement',
|
|
54
|
+
reasonCode: 'mobile_window_management_unsupported',
|
|
55
|
+
}),
|
|
56
|
+
Object.freeze({
|
|
57
|
+
api: 'aura.window.minimize',
|
|
58
|
+
capability: 'windowManagement',
|
|
59
|
+
reasonCode: 'mobile_window_management_unsupported',
|
|
60
|
+
}),
|
|
61
|
+
Object.freeze({
|
|
62
|
+
api: 'aura.window.restore',
|
|
63
|
+
capability: 'windowManagement',
|
|
64
|
+
reasonCode: 'mobile_window_management_unsupported',
|
|
65
|
+
}),
|
|
66
|
+
Object.freeze({
|
|
67
|
+
api: 'aura.window.focus',
|
|
68
|
+
capability: 'windowManagement',
|
|
69
|
+
reasonCode: 'mobile_window_management_unsupported',
|
|
70
|
+
}),
|
|
71
|
+
Object.freeze({
|
|
72
|
+
api: 'aura.window.getSafeAreaInsets',
|
|
73
|
+
capability: 'safeArea',
|
|
74
|
+
reasonCode: 'mobile_safe_area_unavailable',
|
|
75
|
+
}),
|
|
76
|
+
Object.freeze({
|
|
77
|
+
api: 'aura.window.setOrientationLock',
|
|
78
|
+
capability: 'orientationControl',
|
|
79
|
+
reasonCode: 'mobile_orientation_control_unavailable',
|
|
80
|
+
}),
|
|
81
|
+
Object.freeze({
|
|
82
|
+
api: 'aura.input.gyro',
|
|
83
|
+
capability: 'sensor',
|
|
84
|
+
reasonCode: 'mobile_sensor_unavailable',
|
|
85
|
+
}),
|
|
86
|
+
Object.freeze({
|
|
87
|
+
api: 'aura.input.accelerometer',
|
|
88
|
+
capability: 'sensor',
|
|
89
|
+
reasonCode: 'mobile_sensor_unavailable',
|
|
90
|
+
}),
|
|
91
|
+
]);
|
|
92
|
+
|
|
93
|
+
const MOBILE_DEFERRED_SURFACES = Object.freeze([
|
|
94
|
+
Object.freeze({
|
|
95
|
+
surface: 'keyboardFirstControls',
|
|
96
|
+
status: 'deferred',
|
|
97
|
+
reasonCode: 'mobile_keyboard_first_control_deferred',
|
|
98
|
+
}),
|
|
99
|
+
Object.freeze({
|
|
100
|
+
surface: 'multiTouchPublicContract',
|
|
101
|
+
status: 'deferred',
|
|
102
|
+
reasonCode: null,
|
|
103
|
+
}),
|
|
104
|
+
Object.freeze({
|
|
105
|
+
surface: 'orientationControl',
|
|
106
|
+
status: 'deferred',
|
|
107
|
+
reasonCode: 'mobile_orientation_control_unavailable',
|
|
108
|
+
}),
|
|
109
|
+
Object.freeze({
|
|
110
|
+
surface: 'safeArea',
|
|
111
|
+
status: 'deferred',
|
|
112
|
+
reasonCode: 'mobile_safe_area_unavailable',
|
|
113
|
+
}),
|
|
114
|
+
Object.freeze({
|
|
115
|
+
surface: 'sensors',
|
|
116
|
+
status: 'deferred',
|
|
117
|
+
reasonCode: 'mobile_sensor_unavailable',
|
|
118
|
+
}),
|
|
119
|
+
]);
|
|
120
|
+
|
|
121
|
+
function normalizeRequiredApis(requiredApis) {
|
|
122
|
+
if (!Array.isArray(requiredApis)) {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
return [...new Set(requiredApis
|
|
126
|
+
.filter((entry) => typeof entry === 'string')
|
|
127
|
+
.map((entry) => entry.trim())
|
|
128
|
+
.filter(Boolean))]
|
|
129
|
+
.sort((a, b) => a.localeCompare(b));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function normalizeMobileBuildTarget(target) {
|
|
133
|
+
const normalized = typeof target === 'string' ? target.trim().toLowerCase() : '';
|
|
134
|
+
if (!MOBILE_BUILD_TARGETS.has(normalized)) {
|
|
135
|
+
throw new Error(`Unsupported mobile build target: ${target}`);
|
|
136
|
+
}
|
|
137
|
+
return normalized;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function buildMobileCapabilityReport({ target, capabilityDeclaration } = {}) {
|
|
141
|
+
const normalizedTarget = normalizeMobileBuildTarget(target || 'mobile');
|
|
142
|
+
const requiredApis = normalizeRequiredApis(capabilityDeclaration?.requiredApis);
|
|
143
|
+
const unsupportedApis = MOBILE_UNSUPPORTED_API_RULES
|
|
144
|
+
.filter((rule) => requiredApis.includes(rule.api))
|
|
145
|
+
.map((rule) => ({
|
|
146
|
+
api: rule.api,
|
|
147
|
+
capability: rule.capability,
|
|
148
|
+
status: 'unsupported',
|
|
149
|
+
reasonCode: rule.reasonCode,
|
|
150
|
+
}));
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
schema: MOBILE_CAPABILITY_REPORT_SCHEMA,
|
|
154
|
+
schemaVersion: '1.0.0',
|
|
155
|
+
buildTarget: normalizedTarget,
|
|
156
|
+
source: typeof capabilityDeclaration?.source === 'string' ? capabilityDeclaration.source : null,
|
|
157
|
+
reasonCode: unsupportedApis.length > 0
|
|
158
|
+
? 'mobile_required_api_unsupported'
|
|
159
|
+
: 'mobile_capability_contract_ok',
|
|
160
|
+
ok: unsupportedApis.length === 0,
|
|
161
|
+
input: {
|
|
162
|
+
primaryPointer: {
|
|
163
|
+
status: 'supported',
|
|
164
|
+
reasonCode: null,
|
|
165
|
+
},
|
|
166
|
+
multiTouch: {
|
|
167
|
+
status: 'deferred',
|
|
168
|
+
reasonCode: null,
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
unsupportedApis,
|
|
172
|
+
deferredSurfaces: MOBILE_DEFERRED_SURFACES,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
@@ -72,7 +72,7 @@ function readJsonFile(path) {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
function listHashedPackageFiles(root, current = root, acc = []) {
|
|
75
|
+
function listHashedPackageFiles(root, current = root, acc = [], includedPaths = null) {
|
|
76
76
|
for (const entry of readdirSync(current, { withFileTypes: true })) {
|
|
77
77
|
const fullPath = join(current, entry.name);
|
|
78
78
|
const relativePath = normalizeRelativePath(relative(root, fullPath));
|
|
@@ -92,7 +92,7 @@ function listHashedPackageFiles(root, current = root, acc = []) {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
if (entry.isDirectory()) {
|
|
95
|
-
listHashedPackageFiles(root, fullPath, acc);
|
|
95
|
+
listHashedPackageFiles(root, fullPath, acc, includedPaths);
|
|
96
96
|
continue;
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -100,6 +100,10 @@ function listHashedPackageFiles(root, current = root, acc = []) {
|
|
|
100
100
|
continue;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
if (includedPaths && !includedPaths.has(relativePath)) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
|
|
103
107
|
const buffer = readFileSync(fullPath);
|
|
104
108
|
acc.push({
|
|
105
109
|
path: relativePath,
|
|
@@ -198,8 +202,16 @@ function normalizeBuildMetadata(buildMetadata = {}) {
|
|
|
198
202
|
};
|
|
199
203
|
}
|
|
200
204
|
|
|
201
|
-
function buildManifestBody({ packageRoot, projectPackage, buildMetadata = null, signer }) {
|
|
205
|
+
function buildManifestBody({ packageRoot, projectPackage, buildMetadata = null, signer, includedRelativePaths = null }) {
|
|
202
206
|
const resolvedPackage = projectPackage || readJsonFile(resolve(packageRoot, 'package.json'));
|
|
207
|
+
const normalizedIncludedPaths = Array.isArray(includedRelativePaths)
|
|
208
|
+
? new Set(
|
|
209
|
+
includedRelativePaths
|
|
210
|
+
.map((entry) => normalizeRelativePath(entry))
|
|
211
|
+
.filter(Boolean)
|
|
212
|
+
.filter((entry) => entry !== PACKAGE_INTEGRITY_MANIFEST_PATH && entry !== PACKAGE_INTEGRITY_SIGNATURE_PATH),
|
|
213
|
+
)
|
|
214
|
+
: null;
|
|
203
215
|
return {
|
|
204
216
|
schema: PACKAGE_INTEGRITY_SCHEMA,
|
|
205
217
|
package: {
|
|
@@ -219,7 +231,7 @@ function buildManifestBody({ packageRoot, projectPackage, buildMetadata = null,
|
|
|
219
231
|
publicKeyPem: signer.publicKeyPem,
|
|
220
232
|
fingerprint: signer.fingerprint,
|
|
221
233
|
},
|
|
222
|
-
files: listHashedPackageFiles(packageRoot),
|
|
234
|
+
files: listHashedPackageFiles(packageRoot, packageRoot, [], normalizedIncludedPaths),
|
|
223
235
|
};
|
|
224
236
|
}
|
|
225
237
|
|
|
@@ -512,6 +524,7 @@ export function writeSignedPackageIntegrityArtifacts({
|
|
|
512
524
|
signerProjectRoot = packageRoot,
|
|
513
525
|
buildMetadata = null,
|
|
514
526
|
projectPackage = null,
|
|
527
|
+
includedRelativePaths = null,
|
|
515
528
|
} = {}) {
|
|
516
529
|
const resolvedPackageRoot = resolve(packageRoot || process.cwd());
|
|
517
530
|
const signer = ensureSignerKeyPair(resolve(signerProjectRoot || resolvedPackageRoot));
|
|
@@ -520,6 +533,7 @@ export function writeSignedPackageIntegrityArtifacts({
|
|
|
520
533
|
projectPackage,
|
|
521
534
|
buildMetadata,
|
|
522
535
|
signer,
|
|
536
|
+
includedRelativePaths,
|
|
523
537
|
});
|
|
524
538
|
const signature = sign(
|
|
525
539
|
null,
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, relative, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
export const PACK_CATALOG_SCHEMA = 'aurajs.pack-catalog.v1';
|
|
6
|
+
export const PROJECT_PACKS_SCHEMA = 'aurajs.project-packs.v1';
|
|
7
|
+
export const PROJECT_PACKS_MANIFEST_PATH = 'aura.packs.json';
|
|
8
|
+
|
|
9
|
+
const PACKS_DIR = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const CLI_PACKAGE_ROOT = resolve(PACKS_DIR, '../..');
|
|
11
|
+
const REPO_ROOT = resolve(CLI_PACKAGE_ROOT, '../..');
|
|
12
|
+
const WORKSPACE_PACKAGES_ROOT = resolve(REPO_ROOT, 'packages');
|
|
13
|
+
const CLI_PACKAGE = JSON.parse(readFileSync(resolve(CLI_PACKAGE_ROOT, 'package.json'), 'utf8'));
|
|
14
|
+
const CLI_PACKAGE_VERSION = String(CLI_PACKAGE.version || '0.1.0');
|
|
15
|
+
const PUBLIC_PACK_GITHUB_REPOSITORY = 'Aura-Industry/auramaxx';
|
|
16
|
+
|
|
17
|
+
function createPublicPackGithub(packDirName) {
|
|
18
|
+
return {
|
|
19
|
+
repository: PUBLIC_PACK_GITHUB_REPOSITORY,
|
|
20
|
+
ref: 'main',
|
|
21
|
+
packPath: `packs/${packDirName}`,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const PACK_REGISTRY = [
|
|
26
|
+
{
|
|
27
|
+
id: 'ai-starters',
|
|
28
|
+
kind: 'starter-pack',
|
|
29
|
+
title: 'AI Starters',
|
|
30
|
+
description: 'AI-first recipes, prompts, and starter overlays for AuraJS projects.',
|
|
31
|
+
packageName: '@auraindustry/aurajs-pack-ai-starters',
|
|
32
|
+
workspaceDirName: 'aurajs-pack-ai-starters',
|
|
33
|
+
surfaces: ['recipes', 'skills', 'starter-overlays'],
|
|
34
|
+
recommendedFor: ['ai', '2d', 'starter-authoring'],
|
|
35
|
+
github: createPublicPackGithub('aurajs-pack-ai-starters'),
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: 'assets-2d-core',
|
|
39
|
+
kind: 'asset-pack',
|
|
40
|
+
title: '2D Core Assets',
|
|
41
|
+
description: 'Optional placeholder-ready 2D palette, HUD, and audio planning assets.',
|
|
42
|
+
packageName: '@auraindustry/aurajs-pack-assets-2d-core',
|
|
43
|
+
workspaceDirName: 'aurajs-pack-assets-2d-core',
|
|
44
|
+
surfaces: ['assets', 'palettes', 'audio-planning'],
|
|
45
|
+
recommendedFor: ['2d', 'prototype', 'placeholder-art'],
|
|
46
|
+
github: createPublicPackGithub('aurajs-pack-assets-2d-core'),
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'ui-hud-2d',
|
|
50
|
+
kind: 'ui-pack',
|
|
51
|
+
title: 'UI HUD 2D',
|
|
52
|
+
description: 'Reusable 2D HUD themes, layout payloads, and widget planning files.',
|
|
53
|
+
packageName: '@auraindustry/aurajs-pack-ui-hud-2d',
|
|
54
|
+
workspaceDirName: 'aurajs-pack-ui-hud-2d',
|
|
55
|
+
surfaces: ['themes', 'layouts', 'widgets'],
|
|
56
|
+
recommendedFor: ['2d', 'hud', 'ui'],
|
|
57
|
+
github: createPublicPackGithub('aurajs-pack-ui-hud-2d'),
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: 'audio-2d-core',
|
|
61
|
+
kind: 'audio-pack',
|
|
62
|
+
title: 'Audio 2D Core',
|
|
63
|
+
description: 'Structured 2D scene audio defaults, bus layout, stingers, and bark planning payloads.',
|
|
64
|
+
packageName: '@auraindustry/aurajs-pack-audio-2d-core',
|
|
65
|
+
workspaceDirName: 'aurajs-pack-audio-2d-core',
|
|
66
|
+
surfaces: ['audio-config', 'barks', 'stingers'],
|
|
67
|
+
recommendedFor: ['2d', 'audio', 'scene-audio'],
|
|
68
|
+
github: createPublicPackGithub('aurajs-pack-audio-2d-core'),
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
const BUNDLE_REGISTRY = [
|
|
73
|
+
{
|
|
74
|
+
id: 'ai-2d-bundle',
|
|
75
|
+
kind: 'bundle',
|
|
76
|
+
title: 'AI 2D Bundle',
|
|
77
|
+
description: 'Recommended optional pack set for AI-assisted 2D AuraJS projects.',
|
|
78
|
+
packageName: '@auraindustry/aurajs-bundle-ai-2d',
|
|
79
|
+
workspaceDirName: 'aurajs-bundle-ai-2d',
|
|
80
|
+
memberPackIds: ['ai-starters', 'assets-2d-core', 'ui-hud-2d', 'audio-2d-core'],
|
|
81
|
+
recommendedFor: ['ai', '2d', 'flagship-prototype'],
|
|
82
|
+
github: createPublicPackGithub('aurajs-bundle-ai-2d'),
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
function toPosixPath(value) {
|
|
87
|
+
return String(value || '').split(/[/\\]+/g).filter(Boolean).join('/');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function normalizeRelativeFileSpec(projectRoot, targetRoot) {
|
|
91
|
+
const relativePath = relative(projectRoot, targetRoot);
|
|
92
|
+
const normalized = toPosixPath(relativePath);
|
|
93
|
+
if (!normalized || normalized === '.') {
|
|
94
|
+
return 'file:.';
|
|
95
|
+
}
|
|
96
|
+
if (normalized.startsWith('.')) {
|
|
97
|
+
return `file:${normalized}`;
|
|
98
|
+
}
|
|
99
|
+
return `file:./${normalized}`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function buildPackEntry(entry) {
|
|
103
|
+
const workspacePath = resolve(WORKSPACE_PACKAGES_ROOT, entry.workspaceDirName);
|
|
104
|
+
return {
|
|
105
|
+
...entry,
|
|
106
|
+
workspacePath,
|
|
107
|
+
workspaceAvailable: existsSync(workspacePath),
|
|
108
|
+
versionRange: `^${CLI_PACKAGE_VERSION}`,
|
|
109
|
+
github: entry.github ? { ...entry.github } : null,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function buildBundleEntry(entry) {
|
|
114
|
+
const workspacePath = resolve(WORKSPACE_PACKAGES_ROOT, entry.workspaceDirName);
|
|
115
|
+
return {
|
|
116
|
+
...entry,
|
|
117
|
+
workspacePath,
|
|
118
|
+
workspaceAvailable: existsSync(workspacePath),
|
|
119
|
+
versionRange: `^${CLI_PACKAGE_VERSION}`,
|
|
120
|
+
github: entry.github ? { ...entry.github } : null,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function listPackRegistry() {
|
|
125
|
+
return PACK_REGISTRY.map(buildPackEntry);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function listBundleRegistry() {
|
|
129
|
+
return BUNDLE_REGISTRY.map(buildBundleEntry);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function findPackEntry(id) {
|
|
133
|
+
return listPackRegistry().find((entry) => entry.id === id) || null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function findBundleEntry(id) {
|
|
137
|
+
return listBundleRegistry().find((entry) => entry.id === id) || null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function findPackOrBundleEntry(id) {
|
|
141
|
+
return findPackEntry(id) || findBundleEntry(id);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function expandPackSelection(id) {
|
|
145
|
+
const pack = findPackEntry(id);
|
|
146
|
+
if (pack) {
|
|
147
|
+
return {
|
|
148
|
+
requested: pack,
|
|
149
|
+
bundles: [],
|
|
150
|
+
packs: [pack],
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const bundle = findBundleEntry(id);
|
|
154
|
+
if (!bundle) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
const packs = bundle.memberPackIds
|
|
158
|
+
.map((memberId) => findPackEntry(memberId))
|
|
159
|
+
.filter(Boolean);
|
|
160
|
+
return {
|
|
161
|
+
requested: bundle,
|
|
162
|
+
bundles: [bundle],
|
|
163
|
+
packs,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function resolvePackInstallSpec(entry, { projectRoot, workspace = false } = {}) {
|
|
168
|
+
if (workspace && projectRoot && entry.workspaceAvailable) {
|
|
169
|
+
return {
|
|
170
|
+
mode: 'workspace',
|
|
171
|
+
spec: normalizeRelativeFileSpec(projectRoot, entry.workspacePath),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
mode: 'package',
|
|
176
|
+
spec: entry.versionRange,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function createPackCatalogReport() {
|
|
181
|
+
return {
|
|
182
|
+
schema: PACK_CATALOG_SCHEMA,
|
|
183
|
+
corePackage: CLI_PACKAGE.name,
|
|
184
|
+
coreVersion: CLI_PACKAGE_VERSION,
|
|
185
|
+
packs: listPackRegistry().map((entry) => ({
|
|
186
|
+
id: entry.id,
|
|
187
|
+
kind: entry.kind,
|
|
188
|
+
title: entry.title,
|
|
189
|
+
description: entry.description,
|
|
190
|
+
packageName: entry.packageName,
|
|
191
|
+
versionRange: entry.versionRange,
|
|
192
|
+
workspaceAvailable: entry.workspaceAvailable,
|
|
193
|
+
github: entry.github ? { ...entry.github } : null,
|
|
194
|
+
recommendedFor: [...entry.recommendedFor],
|
|
195
|
+
surfaces: [...entry.surfaces],
|
|
196
|
+
})),
|
|
197
|
+
bundles: listBundleRegistry().map((entry) => ({
|
|
198
|
+
id: entry.id,
|
|
199
|
+
kind: entry.kind,
|
|
200
|
+
title: entry.title,
|
|
201
|
+
description: entry.description,
|
|
202
|
+
packageName: entry.packageName,
|
|
203
|
+
versionRange: entry.versionRange,
|
|
204
|
+
workspaceAvailable: entry.workspaceAvailable,
|
|
205
|
+
github: entry.github ? { ...entry.github } : null,
|
|
206
|
+
recommendedFor: [...entry.recommendedFor],
|
|
207
|
+
memberPackIds: [...entry.memberPackIds],
|
|
208
|
+
})),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export function normalizeProjectPackManifest(value) {
|
|
213
|
+
const safe = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
214
|
+
return {
|
|
215
|
+
schema: PROJECT_PACKS_SCHEMA,
|
|
216
|
+
selected: Array.isArray(safe.selected)
|
|
217
|
+
? safe.selected
|
|
218
|
+
.filter((entry) => entry && typeof entry === 'object' && !Array.isArray(entry))
|
|
219
|
+
.map((entry) => ({
|
|
220
|
+
id: typeof entry.id === 'string' ? entry.id : null,
|
|
221
|
+
kind: typeof entry.kind === 'string' ? entry.kind : 'starter-pack',
|
|
222
|
+
sourceMode: entry.sourceMode === 'github'
|
|
223
|
+
? 'github'
|
|
224
|
+
: entry.sourceMode === 'workspace'
|
|
225
|
+
? 'workspace'
|
|
226
|
+
: 'package',
|
|
227
|
+
}))
|
|
228
|
+
.filter((entry) => entry.id)
|
|
229
|
+
: [],
|
|
230
|
+
packs: Array.isArray(safe.packs)
|
|
231
|
+
? safe.packs
|
|
232
|
+
.filter((entry) => entry && typeof entry === 'object' && !Array.isArray(entry))
|
|
233
|
+
.map((entry) => ({
|
|
234
|
+
id: typeof entry.id === 'string' ? entry.id : null,
|
|
235
|
+
kind: typeof entry.kind === 'string' ? entry.kind : 'starter-pack',
|
|
236
|
+
packageName: typeof entry.packageName === 'string' ? entry.packageName : null,
|
|
237
|
+
spec: typeof entry.spec === 'string' ? entry.spec : null,
|
|
238
|
+
installMode: entry.installMode === 'workspace' ? 'workspace' : 'package',
|
|
239
|
+
sourceMode: entry.sourceMode === 'github'
|
|
240
|
+
? 'github'
|
|
241
|
+
: entry.sourceMode === 'workspace'
|
|
242
|
+
? 'workspace'
|
|
243
|
+
: 'package',
|
|
244
|
+
vendoredPaths: Array.isArray(entry.vendoredPaths) ? entry.vendoredPaths.map((item) => String(item)) : [],
|
|
245
|
+
}))
|
|
246
|
+
.filter((entry) => entry.id)
|
|
247
|
+
: [],
|
|
248
|
+
bundles: Array.isArray(safe.bundles)
|
|
249
|
+
? safe.bundles
|
|
250
|
+
.filter((entry) => entry && typeof entry === 'object' && !Array.isArray(entry))
|
|
251
|
+
.map((entry) => ({
|
|
252
|
+
id: typeof entry.id === 'string' ? entry.id : null,
|
|
253
|
+
packageName: typeof entry.packageName === 'string' ? entry.packageName : null,
|
|
254
|
+
memberPackIds: Array.isArray(entry.memberPackIds) ? entry.memberPackIds.map((item) => String(item)) : [],
|
|
255
|
+
}))
|
|
256
|
+
.filter((entry) => entry.id)
|
|
257
|
+
: [],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
@@ -77,19 +77,24 @@ function parseCliArgs(argv) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
function mapApplicableScenes(report, sceneThresholds = {}) {
|
|
80
|
-
const
|
|
80
|
+
const scenesById = new Map((report?.scenes || []).map((scene) => [scene.id, scene]));
|
|
81
81
|
return Object.entries(sceneThresholds)
|
|
82
|
-
.filter(([sceneId]) =>
|
|
83
|
-
.map(([sceneId, limits]) =>
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
82
|
+
.filter(([sceneId]) => scenesById.has(sceneId))
|
|
83
|
+
.map(([sceneId, limits]) => {
|
|
84
|
+
const scene = scenesById.get(sceneId) || {};
|
|
85
|
+
return {
|
|
86
|
+
id: sceneId,
|
|
87
|
+
lane: typeof scene.lane === 'string' ? scene.lane : null,
|
|
88
|
+
surfaceTags: Array.isArray(scene.surfaceTags) ? [...scene.surfaceTags] : [],
|
|
89
|
+
maxAvgFrameTimeMs: limits.maxAvgFrameTimeMs,
|
|
90
|
+
maxJitterMs: limits.maxJitterMs,
|
|
91
|
+
minFps: limits.minFps,
|
|
92
|
+
maxP50FrameTimeMs: limits.maxP50FrameTimeMs,
|
|
93
|
+
maxP95FrameTimeMs: limits.maxP95FrameTimeMs,
|
|
94
|
+
maxP99FrameTimeMs: limits.maxP99FrameTimeMs,
|
|
95
|
+
maxStutterBurstCount: limits.maxStutterBurstCount,
|
|
96
|
+
};
|
|
97
|
+
});
|
|
93
98
|
}
|
|
94
99
|
|
|
95
100
|
function bucketFailures(failures) {
|