@auraindustry/aurajs 0.1.3 → 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/authored-project.mjs +498 -2
- 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 +265 -4
- package/src/conformance-mobile.mjs +166 -0
- package/src/conformance.mjs +89 -30
- package/src/evidence-bundle.mjs +242 -0
- 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/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 +303 -6
- 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 +43 -1
- package/src/scaffold.mjs +4 -0
- package/src/session-runtime.mjs +4 -3
- package/src/web-conformance.mjs +0 -36
- 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/3d/scenes/gameplay.scene.js +30 -3
- 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/capabilities.js +5 -0
- package/templates/create/3d-collectathon/src/runtime/materials.js +10 -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-bin/play.js +36 -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/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
package/src/authored-project.mjs
CHANGED
|
@@ -11,6 +11,13 @@ import {
|
|
|
11
11
|
validateStarterContentRegistries,
|
|
12
12
|
} from './starter-content-registry.mjs';
|
|
13
13
|
import { loadMakeCatalog } from './make-catalog.mjs';
|
|
14
|
+
import { describeProjectAiGuidance, normalizeAiGuidance } from './ai-guidance.mjs';
|
|
15
|
+
import {
|
|
16
|
+
PROJECT_PACKS_MANIFEST_PATH,
|
|
17
|
+
findPackOrBundleEntry,
|
|
18
|
+
listPackRegistry,
|
|
19
|
+
normalizeProjectPackManifest,
|
|
20
|
+
} from './packs/catalog.mjs';
|
|
14
21
|
|
|
15
22
|
export const PROJECT_REGISTRY_SCHEMA = 'aurajs.project-registry.v1';
|
|
16
23
|
export const PROJECT_EXPLAIN_SCHEMA = 'aurajs.project-explain.v1';
|
|
@@ -29,6 +36,14 @@ const RUNTIME_BOOTSTRAP_FILES = [
|
|
|
29
36
|
const SELF_WIRING_KINDS = new Set(['scene', 'ui-screen', 'prefab']);
|
|
30
37
|
const CANONICAL_PREFAB_ROLE_SET = new Set(CANONICAL_PREFAB_ROLES);
|
|
31
38
|
const POSIX_SEP = '/';
|
|
39
|
+
const AUTHORED_SOURCE_ROOT_DIRS = Object.freeze(['src', 'scenes', 'ui', 'prefabs', 'config', 'content', 'data']);
|
|
40
|
+
const STARTER_UTILS_ROOT_RELATIVE_PATH = 'src/starter-utils';
|
|
41
|
+
const PROJECT_PACKS_RELATIVE_PATH = PROJECT_PACKS_MANIFEST_PATH;
|
|
42
|
+
const SHARED_HELPER_PACKAGE_SPECIFIER = '@auraindustry/aurajs/helpers';
|
|
43
|
+
const SUPPORTED_HELPER_PACKAGE_SPECIFIERS = Object.freeze([
|
|
44
|
+
SHARED_HELPER_PACKAGE_SPECIFIER,
|
|
45
|
+
`${SHARED_HELPER_PACKAGE_SPECIFIER}/2d`,
|
|
46
|
+
]);
|
|
32
47
|
|
|
33
48
|
const BASE_PROJECT_CONFIG_FILES = ['config/gameplay/game.config.json'];
|
|
34
49
|
const BASE_PROJECT_CONTENT_FILES = [];
|
|
@@ -57,6 +72,7 @@ const STARTER_PROJECT_REGISTRY_PRESETS = {
|
|
|
57
72
|
],
|
|
58
73
|
screens: [
|
|
59
74
|
{ id: 'hud', path: 'ui/hud.screen.js', exportName: 'default' },
|
|
75
|
+
{ id: 'journal', path: 'ui/journal.screen.js', exportName: 'default' },
|
|
60
76
|
],
|
|
61
77
|
prefabs: [
|
|
62
78
|
{ id: 'player', role: 'player', path: 'prefabs/player.prefab.js', exportName: 'default' },
|
|
@@ -64,7 +80,7 @@ const STARTER_PROJECT_REGISTRY_PRESETS = {
|
|
|
64
80
|
{ id: 'world', role: 'world', path: 'prefabs/world.prefab.js', exportName: 'default' },
|
|
65
81
|
],
|
|
66
82
|
configFiles: ['config/gameplay/adventure.config.js'],
|
|
67
|
-
contentFiles: ['content/gameplay/world.js'],
|
|
83
|
+
contentFiles: ['content/gameplay/dialogue.js', 'content/gameplay/world.js', 'content/gameplay/world.tilemap.json'],
|
|
68
84
|
},
|
|
69
85
|
'2d-shooter': {
|
|
70
86
|
startSceneId: 'gameplay',
|
|
@@ -555,6 +571,10 @@ export async function explainProject({ projectRoot, catalogRoot = null }) {
|
|
|
555
571
|
owner: entry.owner,
|
|
556
572
|
scope: entry.scope,
|
|
557
573
|
}));
|
|
574
|
+
const sourceBoundary = describeSourceBoundary(projectRoot);
|
|
575
|
+
const starterUtils = describeStarterUtils(projectRoot);
|
|
576
|
+
const packs = describeProjectPacks(projectRoot);
|
|
577
|
+
const aiGuidance = describeProjectAiGuidance({ template, starterUtils });
|
|
558
578
|
|
|
559
579
|
if (mode === 'bootstrap-only') {
|
|
560
580
|
return {
|
|
@@ -577,6 +597,10 @@ export async function explainProject({ projectRoot, catalogRoot = null }) {
|
|
|
577
597
|
continuity: createProjectContinuityModel(),
|
|
578
598
|
starterContentRegistries,
|
|
579
599
|
availableMakeKinds,
|
|
600
|
+
sourceBoundary,
|
|
601
|
+
starterUtils,
|
|
602
|
+
packs,
|
|
603
|
+
aiGuidance,
|
|
580
604
|
};
|
|
581
605
|
}
|
|
582
606
|
|
|
@@ -605,6 +629,10 @@ export async function explainProject({ projectRoot, catalogRoot = null }) {
|
|
|
605
629
|
continuity: registry.continuity,
|
|
606
630
|
starterContentRegistries,
|
|
607
631
|
availableMakeKinds,
|
|
632
|
+
sourceBoundary,
|
|
633
|
+
starterUtils,
|
|
634
|
+
packs,
|
|
635
|
+
aiGuidance,
|
|
608
636
|
};
|
|
609
637
|
}
|
|
610
638
|
|
|
@@ -622,9 +650,17 @@ export async function checkProject({ projectRoot, catalogRoot = null }) {
|
|
|
622
650
|
reasonCode: 'project_root_missing',
|
|
623
651
|
errors: [{ reasonCode: 'project_root_missing', message: 'Missing aura.config.json in the current directory.' }],
|
|
624
652
|
warnings,
|
|
653
|
+
sourceBoundary: null,
|
|
654
|
+
starterUtils: null,
|
|
655
|
+
aiGuidance: null,
|
|
625
656
|
});
|
|
626
657
|
}
|
|
627
658
|
|
|
659
|
+
const sourceBoundary = describeSourceBoundary(projectRoot);
|
|
660
|
+
const starterUtils = describeStarterUtils(projectRoot);
|
|
661
|
+
const packs = describeProjectPacks(projectRoot);
|
|
662
|
+
const aiGuidance = describeProjectAiGuidance({ template, starterUtils });
|
|
663
|
+
|
|
628
664
|
if (!existsSync(registryPath)) {
|
|
629
665
|
if (template === 'blank' && !hasAuthoredProjectFiles(projectRoot)) {
|
|
630
666
|
return buildProjectCheckResult({
|
|
@@ -633,6 +669,10 @@ export async function checkProject({ projectRoot, catalogRoot = null }) {
|
|
|
633
669
|
reasonCode: 'bootstrap_only_project_ok',
|
|
634
670
|
errors,
|
|
635
671
|
warnings,
|
|
672
|
+
sourceBoundary,
|
|
673
|
+
starterUtils,
|
|
674
|
+
packs,
|
|
675
|
+
aiGuidance,
|
|
636
676
|
});
|
|
637
677
|
}
|
|
638
678
|
return buildProjectCheckResult({
|
|
@@ -641,6 +681,10 @@ export async function checkProject({ projectRoot, catalogRoot = null }) {
|
|
|
641
681
|
reasonCode: 'project_registry_missing',
|
|
642
682
|
errors: [{ reasonCode: 'project_registry_missing', message: 'Missing src/runtime/project-registry.js.' }],
|
|
643
683
|
warnings,
|
|
684
|
+
sourceBoundary,
|
|
685
|
+
starterUtils,
|
|
686
|
+
packs,
|
|
687
|
+
aiGuidance,
|
|
644
688
|
});
|
|
645
689
|
}
|
|
646
690
|
|
|
@@ -658,6 +702,10 @@ export async function checkProject({ projectRoot, catalogRoot = null }) {
|
|
|
658
702
|
path: PROJECT_REGISTRY_RELATIVE_PATH,
|
|
659
703
|
}],
|
|
660
704
|
warnings,
|
|
705
|
+
sourceBoundary,
|
|
706
|
+
starterUtils,
|
|
707
|
+
packs,
|
|
708
|
+
aiGuidance,
|
|
661
709
|
});
|
|
662
710
|
}
|
|
663
711
|
|
|
@@ -705,6 +753,10 @@ export async function checkProject({ projectRoot, catalogRoot = null }) {
|
|
|
705
753
|
errors,
|
|
706
754
|
warnings,
|
|
707
755
|
starterContentRegistries: starterContentValidation.registries,
|
|
756
|
+
sourceBoundary,
|
|
757
|
+
starterUtils,
|
|
758
|
+
packs,
|
|
759
|
+
aiGuidance,
|
|
708
760
|
});
|
|
709
761
|
}
|
|
710
762
|
|
|
@@ -954,7 +1006,22 @@ function devRestoreOrFallback(value) {
|
|
|
954
1006
|
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
955
1007
|
}
|
|
956
1008
|
|
|
957
|
-
function buildProjectCheckResult({
|
|
1009
|
+
function buildProjectCheckResult({
|
|
1010
|
+
mode,
|
|
1011
|
+
ok,
|
|
1012
|
+
reasonCode,
|
|
1013
|
+
errors,
|
|
1014
|
+
warnings,
|
|
1015
|
+
starterContentRegistries = [],
|
|
1016
|
+
sourceBoundary = null,
|
|
1017
|
+
starterUtils = null,
|
|
1018
|
+
packs = null,
|
|
1019
|
+
aiGuidance = null,
|
|
1020
|
+
}) {
|
|
1021
|
+
const normalizedSourceBoundary = normalizeSourceBoundary(sourceBoundary);
|
|
1022
|
+
const normalizedStarterUtils = normalizeStarterUtils(starterUtils);
|
|
1023
|
+
const normalizedPacks = normalizeProjectPacks(packs);
|
|
1024
|
+
const normalizedAiGuidance = normalizeAiGuidance(aiGuidance);
|
|
958
1025
|
return {
|
|
959
1026
|
schema: PROJECT_CHECK_SCHEMA,
|
|
960
1027
|
ok,
|
|
@@ -963,6 +1030,16 @@ function buildProjectCheckResult({ mode, ok, reasonCode, errors, warnings, start
|
|
|
963
1030
|
errors,
|
|
964
1031
|
warnings,
|
|
965
1032
|
starterContentRegistries,
|
|
1033
|
+
sourceBoundary: normalizedSourceBoundary,
|
|
1034
|
+
starterUtils: normalizedStarterUtils,
|
|
1035
|
+
packs: normalizedPacks,
|
|
1036
|
+
aiGuidance: normalizedAiGuidance,
|
|
1037
|
+
surfaceDrift: describeProjectSurfaceDrift({
|
|
1038
|
+
mode,
|
|
1039
|
+
sourceBoundary: normalizedSourceBoundary,
|
|
1040
|
+
starterUtils: normalizedStarterUtils,
|
|
1041
|
+
aiGuidance: normalizedAiGuidance,
|
|
1042
|
+
}),
|
|
966
1043
|
};
|
|
967
1044
|
}
|
|
968
1045
|
|
|
@@ -998,6 +1075,43 @@ function formatExplainReport(report) {
|
|
|
998
1075
|
}
|
|
999
1076
|
}
|
|
1000
1077
|
|
|
1078
|
+
lines.push('');
|
|
1079
|
+
lines.push('Authoring boundary:');
|
|
1080
|
+
if (!Array.isArray(report.sourceBoundary?.authoredRoots) || report.sourceBoundary.authoredRoots.length === 0) {
|
|
1081
|
+
lines.push(' authored roots: (none detected)');
|
|
1082
|
+
} else {
|
|
1083
|
+
lines.push(` authored roots: ${report.sourceBoundary.authoredRoots.join(', ')}`);
|
|
1084
|
+
}
|
|
1085
|
+
if (!Array.isArray(report.sourceBoundary?.supportedPackageImports) || report.sourceBoundary.supportedPackageImports.length === 0) {
|
|
1086
|
+
lines.push(' supported shared imports: (none)');
|
|
1087
|
+
} else {
|
|
1088
|
+
lines.push(` supported shared imports: ${report.sourceBoundary.supportedPackageImports.join(', ')}`);
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
lines.push('');
|
|
1092
|
+
lines.push('Starter helper lane:');
|
|
1093
|
+
if (report.starterUtils?.available !== true) {
|
|
1094
|
+
lines.push(' (no scaffolded starter-utils copy detected)');
|
|
1095
|
+
} else {
|
|
1096
|
+
lines.push(` root: ${report.starterUtils.rootPath}`);
|
|
1097
|
+
lines.push(` recommended import: ${report.starterUtils.recommendedImportPath || '(none)'}`);
|
|
1098
|
+
lines.push(` default package: ${report.starterUtils.defaultPackageSpecifier || SHARED_HELPER_PACKAGE_SPECIFIER}`);
|
|
1099
|
+
lines.push(` modules: ${(report.starterUtils.modules || []).map((entry) => `${entry.path} [${entry.mode}]`).join(', ') || '(none)'}`);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
lines.push('');
|
|
1103
|
+
lines.push('AI paved road:');
|
|
1104
|
+
lines.push(` lane: ${report.aiGuidance?.laneId || 'bootstrap-authored-project'}`);
|
|
1105
|
+
if (report.aiGuidance?.summary) {
|
|
1106
|
+
lines.push(` summary: ${report.aiGuidance.summary}`);
|
|
1107
|
+
}
|
|
1108
|
+
lines.push(` preferred import: ${report.aiGuidance?.recommendedImportPath || report.aiGuidance?.preferredPackageSpecifier || '(none)'}`);
|
|
1109
|
+
if (!Array.isArray(report.aiGuidance?.recommendedModules) || report.aiGuidance.recommendedModules.length === 0) {
|
|
1110
|
+
lines.push(' recommended modules: (none)');
|
|
1111
|
+
} else {
|
|
1112
|
+
lines.push(` recommended modules: ${report.aiGuidance.recommendedModules.map((entry) => `${entry.id} -> ${entry.preferredImportSource}`).join(', ')}`);
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1001
1115
|
lines.push('');
|
|
1002
1116
|
lines.push('Scenes:');
|
|
1003
1117
|
if ((report.scenes || []).length === 0) {
|
|
@@ -1088,6 +1202,22 @@ function formatExplainReport(report) {
|
|
|
1088
1202
|
}
|
|
1089
1203
|
}
|
|
1090
1204
|
|
|
1205
|
+
lines.push('');
|
|
1206
|
+
lines.push('Optional packs:');
|
|
1207
|
+
if (!Array.isArray(report.packs?.selected) || report.packs.selected.length === 0) {
|
|
1208
|
+
lines.push(' (none selected)');
|
|
1209
|
+
} else {
|
|
1210
|
+
for (const entry of report.packs.selected) {
|
|
1211
|
+
lines.push(` ${entry.id} -> ${entry.packageName || '(unknown package)'}${entry.spec ? ` [${entry.spec}]` : ''} (${entry.sourceMode || 'package'})`);
|
|
1212
|
+
if (Array.isArray(entry.vendoredPaths) && entry.vendoredPaths.length > 0) {
|
|
1213
|
+
lines.push(` vendored: ${entry.vendoredPaths.join(', ')}`);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
for (const entry of report.packs?.bundles || []) {
|
|
1217
|
+
lines.push(` bundle ${entry.id} -> ${(entry.memberPackIds || []).join(', ') || '(none)'}`);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1091
1221
|
return `${lines.join('\n')}\n`;
|
|
1092
1222
|
}
|
|
1093
1223
|
|
|
@@ -1098,6 +1228,15 @@ function formatCheckReport(report) {
|
|
|
1098
1228
|
`Reason code: ${report.reasonCode}`,
|
|
1099
1229
|
];
|
|
1100
1230
|
|
|
1231
|
+
lines.push('');
|
|
1232
|
+
lines.push(`Authoring boundary: ${(report.sourceBoundary?.authoredRoots || []).join(', ') || '(none detected)'}`);
|
|
1233
|
+
lines.push(`Starter helper lane: ${report.starterUtils?.available === true ? report.starterUtils.recommendedImportPath || report.starterUtils.rootPath : '(not scaffolded)'}`);
|
|
1234
|
+
lines.push(`Optional packs: ${Array.isArray(report.packs?.selected) && report.packs.selected.length > 0 ? report.packs.selected.map((entry) => entry.id).join(', ') : '(none selected)'}`);
|
|
1235
|
+
lines.push(`AI paved road: ${report.aiGuidance?.laneId || 'bootstrap-authored-project'}`);
|
|
1236
|
+
if (report.surfaceDrift) {
|
|
1237
|
+
lines.push(`Surface status: boundary=${report.surfaceDrift.sourceBoundary.reasonCode}, helpers=${report.surfaceDrift.starterUtils.reasonCode}, lane=${report.surfaceDrift.starterLane.reasonCode}`);
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1101
1240
|
if ((report.errors || []).length > 0) {
|
|
1102
1241
|
lines.push('');
|
|
1103
1242
|
lines.push('Errors:');
|
|
@@ -1349,6 +1488,354 @@ function normalizeProjectRelativePath(value) {
|
|
|
1349
1488
|
return String(value || '').split(/[/\\]+/g).filter(Boolean).join(POSIX_SEP);
|
|
1350
1489
|
}
|
|
1351
1490
|
|
|
1491
|
+
function describeSourceBoundary(projectRoot) {
|
|
1492
|
+
return {
|
|
1493
|
+
authoredRoots: AUTHORED_SOURCE_ROOT_DIRS
|
|
1494
|
+
.filter((relativePath) => existsSync(resolve(projectRoot, relativePath)))
|
|
1495
|
+
.map((relativePath) => normalizeProjectRelativePath(relativePath)),
|
|
1496
|
+
supportedPackageImports: [...SUPPORTED_HELPER_PACKAGE_SPECIFIERS],
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
function describeStarterUtils(projectRoot) {
|
|
1501
|
+
const starterUtilsRoot = resolve(projectRoot, STARTER_UTILS_ROOT_RELATIVE_PATH);
|
|
1502
|
+
if (!existsSync(starterUtilsRoot)) {
|
|
1503
|
+
return {
|
|
1504
|
+
available: false,
|
|
1505
|
+
rootPath: STARTER_UTILS_ROOT_RELATIVE_PATH,
|
|
1506
|
+
recommendedImportPath: null,
|
|
1507
|
+
defaultPackageSpecifier: SHARED_HELPER_PACKAGE_SPECIFIER,
|
|
1508
|
+
supportedPackageSpecifiers: [...SUPPORTED_HELPER_PACKAGE_SPECIFIERS],
|
|
1509
|
+
modules: [],
|
|
1510
|
+
};
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
const modules = readdirSync(starterUtilsRoot)
|
|
1514
|
+
.filter((entry) => /\.(?:js|mjs)$/.test(entry))
|
|
1515
|
+
.sort((left, right) => left.localeCompare(right))
|
|
1516
|
+
.map((entry) => {
|
|
1517
|
+
const absolutePath = resolve(starterUtilsRoot, entry);
|
|
1518
|
+
const source = readFileSync(absolutePath, 'utf8');
|
|
1519
|
+
const packageSpecifier = detectStarterUtilsPackageSpecifier(source);
|
|
1520
|
+
return {
|
|
1521
|
+
path: normalizeProjectRelativePath(`${STARTER_UTILS_ROOT_RELATIVE_PATH}/${entry}`),
|
|
1522
|
+
mode: packageSpecifier ? 'package-facade' : 'authored-local',
|
|
1523
|
+
packageSpecifier: packageSpecifier || null,
|
|
1524
|
+
exports: listNamedExportsFromSource(source),
|
|
1525
|
+
};
|
|
1526
|
+
});
|
|
1527
|
+
|
|
1528
|
+
const indexModule = modules.find((entry) => entry.path === `${STARTER_UTILS_ROOT_RELATIVE_PATH}/index.js`) || null;
|
|
1529
|
+
return {
|
|
1530
|
+
available: true,
|
|
1531
|
+
rootPath: STARTER_UTILS_ROOT_RELATIVE_PATH,
|
|
1532
|
+
recommendedImportPath: indexModule ? './src/starter-utils/index.js' : null,
|
|
1533
|
+
defaultPackageSpecifier: SHARED_HELPER_PACKAGE_SPECIFIER,
|
|
1534
|
+
supportedPackageSpecifiers: [...SUPPORTED_HELPER_PACKAGE_SPECIFIERS],
|
|
1535
|
+
modules,
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
function describeProjectPacks(projectRoot) {
|
|
1540
|
+
const manifestPath = resolve(projectRoot, PROJECT_PACKS_RELATIVE_PATH);
|
|
1541
|
+
const packageJsonPath = resolve(projectRoot, 'package.json');
|
|
1542
|
+
const packageJson = existsSync(packageJsonPath)
|
|
1543
|
+
? JSON.parse(readFileSync(packageJsonPath, 'utf8'))
|
|
1544
|
+
: {};
|
|
1545
|
+
const dependencies = packageJson.dependencies && typeof packageJson.dependencies === 'object'
|
|
1546
|
+
? packageJson.dependencies
|
|
1547
|
+
: {};
|
|
1548
|
+
const manifest = existsSync(manifestPath)
|
|
1549
|
+
? normalizeProjectPackManifest(JSON.parse(readFileSync(manifestPath, 'utf8')))
|
|
1550
|
+
: normalizeProjectPackManifest(null);
|
|
1551
|
+
|
|
1552
|
+
const selectedPacks = manifest.packs.length > 0
|
|
1553
|
+
? manifest.packs.map((entry) => {
|
|
1554
|
+
const catalog = findPackOrBundleEntry(entry.id);
|
|
1555
|
+
return {
|
|
1556
|
+
id: entry.id,
|
|
1557
|
+
kind: entry.kind,
|
|
1558
|
+
packageName: entry.packageName || catalog?.packageName || null,
|
|
1559
|
+
spec: entry.spec || (entry.packageName && typeof dependencies[entry.packageName] === 'string' ? dependencies[entry.packageName] : null),
|
|
1560
|
+
installMode: entry.installMode === 'workspace' ? 'workspace' : 'package',
|
|
1561
|
+
sourceMode: entry.sourceMode === 'github'
|
|
1562
|
+
? 'github'
|
|
1563
|
+
: entry.sourceMode === 'workspace'
|
|
1564
|
+
? 'workspace'
|
|
1565
|
+
: 'package',
|
|
1566
|
+
vendoredPaths: Array.isArray(entry.vendoredPaths) ? entry.vendoredPaths.map((item) => String(item)) : [],
|
|
1567
|
+
title: catalog?.title || null,
|
|
1568
|
+
};
|
|
1569
|
+
})
|
|
1570
|
+
: listPackRegistry()
|
|
1571
|
+
.filter((entry) => typeof dependencies[entry.packageName] === 'string')
|
|
1572
|
+
.map((entry) => ({
|
|
1573
|
+
id: entry.id,
|
|
1574
|
+
kind: entry.kind,
|
|
1575
|
+
packageName: entry.packageName,
|
|
1576
|
+
spec: dependencies[entry.packageName],
|
|
1577
|
+
installMode: String(dependencies[entry.packageName]).startsWith('file:') ? 'workspace' : 'package',
|
|
1578
|
+
sourceMode: String(dependencies[entry.packageName]).startsWith('file:') ? 'workspace' : 'package',
|
|
1579
|
+
vendoredPaths: [],
|
|
1580
|
+
title: entry.title,
|
|
1581
|
+
}));
|
|
1582
|
+
|
|
1583
|
+
return {
|
|
1584
|
+
available: selectedPacks.length > 0 || manifest.bundles.length > 0 || existsSync(manifestPath),
|
|
1585
|
+
manifestPath: existsSync(manifestPath) ? PROJECT_PACKS_RELATIVE_PATH : null,
|
|
1586
|
+
selected: selectedPacks,
|
|
1587
|
+
bundles: manifest.bundles.map((entry) => {
|
|
1588
|
+
const catalog = findPackOrBundleEntry(entry.id);
|
|
1589
|
+
return {
|
|
1590
|
+
id: entry.id,
|
|
1591
|
+
packageName: entry.packageName || catalog?.packageName || null,
|
|
1592
|
+
memberPackIds: Array.isArray(entry.memberPackIds) ? entry.memberPackIds.map((item) => String(item)) : [],
|
|
1593
|
+
github: catalog?.github ? { ...catalog.github } : null,
|
|
1594
|
+
title: catalog?.title || null,
|
|
1595
|
+
};
|
|
1596
|
+
}),
|
|
1597
|
+
};
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
function detectStarterUtilsPackageSpecifier(source) {
|
|
1601
|
+
const match = String(source || '').match(/from ['"](@auraindustry\/aurajs\/helpers(?:\/2d)?)['"]/);
|
|
1602
|
+
return match ? match[1] : null;
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
function listNamedExportsFromSource(source) {
|
|
1606
|
+
const names = [];
|
|
1607
|
+
const seen = new Set();
|
|
1608
|
+
const lines = String(source || '').split(/\r?\n/);
|
|
1609
|
+
|
|
1610
|
+
const pushName = (value) => {
|
|
1611
|
+
if (!value || seen.has(value)) {
|
|
1612
|
+
return;
|
|
1613
|
+
}
|
|
1614
|
+
seen.add(value);
|
|
1615
|
+
names.push(value);
|
|
1616
|
+
};
|
|
1617
|
+
|
|
1618
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
1619
|
+
const trimmed = lines[index].trim();
|
|
1620
|
+
if (!trimmed.startsWith('export ')) {
|
|
1621
|
+
continue;
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1624
|
+
const functionExport = trimmed.match(/^export\s+function\s+([A-Za-z_$][A-Za-z0-9_$]*)\s*\(/);
|
|
1625
|
+
if (functionExport) {
|
|
1626
|
+
pushName(functionExport[1]);
|
|
1627
|
+
continue;
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
const classExport = trimmed.match(/^export\s+class\s+([A-Za-z_$][A-Za-z0-9_$]*)\b/);
|
|
1631
|
+
if (classExport) {
|
|
1632
|
+
pushName(classExport[1]);
|
|
1633
|
+
continue;
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
const variableExport = trimmed.match(/^export\s+(?:const|let|var)\s+([A-Za-z_$][A-Za-z0-9_$]*)\b/);
|
|
1637
|
+
if (variableExport) {
|
|
1638
|
+
pushName(variableExport[1]);
|
|
1639
|
+
continue;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
if (trimmed.startsWith('export {')) {
|
|
1643
|
+
let statement = trimmed;
|
|
1644
|
+
while (!statement.includes('}') && index + 1 < lines.length) {
|
|
1645
|
+
index += 1;
|
|
1646
|
+
statement += ` ${lines[index].trim()}`;
|
|
1647
|
+
}
|
|
1648
|
+
const match = statement.match(/^export\s*\{([^}]+)\}/);
|
|
1649
|
+
if (!match) {
|
|
1650
|
+
continue;
|
|
1651
|
+
}
|
|
1652
|
+
for (const entry of match[1].split(',')) {
|
|
1653
|
+
const spec = entry.trim();
|
|
1654
|
+
if (!spec) continue;
|
|
1655
|
+
const alias = spec.match(/^([A-Za-z_$][A-Za-z0-9_$]*)\s+as\s+([A-Za-z_$][A-Za-z0-9_$]*)$/);
|
|
1656
|
+
pushName(alias ? alias[2] : spec);
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
return names;
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
function normalizeSourceBoundary(boundary) {
|
|
1665
|
+
const safe = boundary && typeof boundary === 'object' && !Array.isArray(boundary) ? boundary : {};
|
|
1666
|
+
return {
|
|
1667
|
+
authoredRoots: Array.isArray(safe.authoredRoots) ? safe.authoredRoots.map((entry) => normalizeProjectRelativePath(entry)) : [],
|
|
1668
|
+
supportedPackageImports: Array.isArray(safe.supportedPackageImports) ? safe.supportedPackageImports.map((entry) => String(entry)) : [],
|
|
1669
|
+
};
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
function normalizeStarterUtils(starterUtils) {
|
|
1673
|
+
const safe = starterUtils && typeof starterUtils === 'object' && !Array.isArray(starterUtils) ? starterUtils : {};
|
|
1674
|
+
return {
|
|
1675
|
+
available: safe.available === true,
|
|
1676
|
+
rootPath: safe.rootPath ? normalizeProjectRelativePath(safe.rootPath) : STARTER_UTILS_ROOT_RELATIVE_PATH,
|
|
1677
|
+
recommendedImportPath: typeof safe.recommendedImportPath === 'string' && safe.recommendedImportPath.trim().length > 0
|
|
1678
|
+
? safe.recommendedImportPath.trim()
|
|
1679
|
+
: null,
|
|
1680
|
+
defaultPackageSpecifier: typeof safe.defaultPackageSpecifier === 'string' && safe.defaultPackageSpecifier.trim().length > 0
|
|
1681
|
+
? safe.defaultPackageSpecifier.trim()
|
|
1682
|
+
: SHARED_HELPER_PACKAGE_SPECIFIER,
|
|
1683
|
+
supportedPackageSpecifiers: Array.isArray(safe.supportedPackageSpecifiers)
|
|
1684
|
+
? safe.supportedPackageSpecifiers.map((entry) => String(entry))
|
|
1685
|
+
: [...SUPPORTED_HELPER_PACKAGE_SPECIFIERS],
|
|
1686
|
+
modules: Array.isArray(safe.modules)
|
|
1687
|
+
? safe.modules.map((entry) => ({
|
|
1688
|
+
path: normalizeProjectRelativePath(entry.path),
|
|
1689
|
+
mode: entry.mode === 'authored-local' ? 'authored-local' : 'package-facade',
|
|
1690
|
+
packageSpecifier: typeof entry.packageSpecifier === 'string' && entry.packageSpecifier.trim().length > 0
|
|
1691
|
+
? entry.packageSpecifier.trim()
|
|
1692
|
+
: null,
|
|
1693
|
+
exports: Array.isArray(entry.exports) ? entry.exports.map((name) => String(name)) : [],
|
|
1694
|
+
}))
|
|
1695
|
+
: [],
|
|
1696
|
+
};
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
function normalizeProjectPacks(packs) {
|
|
1700
|
+
const safe = packs && typeof packs === 'object' && !Array.isArray(packs) ? packs : {};
|
|
1701
|
+
return {
|
|
1702
|
+
available: safe.available === true,
|
|
1703
|
+
manifestPath: typeof safe.manifestPath === 'string' && safe.manifestPath.trim().length > 0
|
|
1704
|
+
? normalizeProjectRelativePath(safe.manifestPath)
|
|
1705
|
+
: null,
|
|
1706
|
+
selected: Array.isArray(safe.selected)
|
|
1707
|
+
? safe.selected.map((entry) => ({
|
|
1708
|
+
id: typeof entry.id === 'string' ? entry.id : null,
|
|
1709
|
+
kind: typeof entry.kind === 'string' ? entry.kind : 'starter-pack',
|
|
1710
|
+
packageName: typeof entry.packageName === 'string' ? entry.packageName : null,
|
|
1711
|
+
spec: typeof entry.spec === 'string' ? entry.spec : null,
|
|
1712
|
+
installMode: entry.installMode === 'workspace' ? 'workspace' : 'package',
|
|
1713
|
+
sourceMode: entry.sourceMode === 'github'
|
|
1714
|
+
? 'github'
|
|
1715
|
+
: entry.sourceMode === 'workspace'
|
|
1716
|
+
? 'workspace'
|
|
1717
|
+
: 'package',
|
|
1718
|
+
vendoredPaths: Array.isArray(entry.vendoredPaths) ? entry.vendoredPaths.map((item) => String(item)) : [],
|
|
1719
|
+
title: typeof entry.title === 'string' ? entry.title : null,
|
|
1720
|
+
})).filter((entry) => entry.id)
|
|
1721
|
+
: [],
|
|
1722
|
+
bundles: Array.isArray(safe.bundles)
|
|
1723
|
+
? safe.bundles.map((entry) => ({
|
|
1724
|
+
id: typeof entry.id === 'string' ? entry.id : null,
|
|
1725
|
+
packageName: typeof entry.packageName === 'string' ? entry.packageName : null,
|
|
1726
|
+
memberPackIds: Array.isArray(entry.memberPackIds) ? entry.memberPackIds.map((item) => String(item)) : [],
|
|
1727
|
+
github: entry.github && typeof entry.github === 'object' && !Array.isArray(entry.github)
|
|
1728
|
+
? {
|
|
1729
|
+
repository: typeof entry.github.repository === 'string' ? entry.github.repository : null,
|
|
1730
|
+
ref: typeof entry.github.ref === 'string' ? entry.github.ref : null,
|
|
1731
|
+
}
|
|
1732
|
+
: null,
|
|
1733
|
+
title: typeof entry.title === 'string' ? entry.title : null,
|
|
1734
|
+
})).filter((entry) => entry.id)
|
|
1735
|
+
: [],
|
|
1736
|
+
};
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
function normalizeSurfaceDrift(value) {
|
|
1740
|
+
const safe = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
1741
|
+
const normalizeEntry = (entry, fallbackReasonCode) => {
|
|
1742
|
+
const source = entry && typeof entry === 'object' && !Array.isArray(entry) ? entry : {};
|
|
1743
|
+
return {
|
|
1744
|
+
status: typeof source.status === 'string' && source.status.trim().length > 0
|
|
1745
|
+
? source.status.trim()
|
|
1746
|
+
: 'info',
|
|
1747
|
+
reasonCode: typeof source.reasonCode === 'string' && source.reasonCode.trim().length > 0
|
|
1748
|
+
? source.reasonCode.trim()
|
|
1749
|
+
: fallbackReasonCode,
|
|
1750
|
+
message: typeof source.message === 'string' && source.message.trim().length > 0
|
|
1751
|
+
? source.message.trim()
|
|
1752
|
+
: null,
|
|
1753
|
+
};
|
|
1754
|
+
};
|
|
1755
|
+
|
|
1756
|
+
return {
|
|
1757
|
+
sourceBoundary: normalizeEntry(safe.sourceBoundary, 'source_boundary_unknown'),
|
|
1758
|
+
starterUtils: normalizeEntry(safe.starterUtils, 'starter_utils_unknown'),
|
|
1759
|
+
starterLane: normalizeEntry(safe.starterLane, 'starter_lane_unknown'),
|
|
1760
|
+
};
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
function describeProjectSurfaceDrift({ mode, sourceBoundary, starterUtils, aiGuidance }) {
|
|
1764
|
+
const authoredRoots = Array.isArray(sourceBoundary?.authoredRoots) ? sourceBoundary.authoredRoots : [];
|
|
1765
|
+
const hasStarterUtils = starterUtils?.available === true;
|
|
1766
|
+
const hasStarterImport = typeof starterUtils?.recommendedImportPath === 'string' && starterUtils.recommendedImportPath.trim().length > 0;
|
|
1767
|
+
const laneId = typeof aiGuidance?.laneId === 'string' && aiGuidance.laneId.trim().length > 0
|
|
1768
|
+
? aiGuidance.laneId.trim()
|
|
1769
|
+
: 'bootstrap-authored-project';
|
|
1770
|
+
const preferredPackageSpecifier = typeof aiGuidance?.preferredPackageSpecifier === 'string' && aiGuidance.preferredPackageSpecifier.trim().length > 0
|
|
1771
|
+
? aiGuidance.preferredPackageSpecifier.trim()
|
|
1772
|
+
: null;
|
|
1773
|
+
|
|
1774
|
+
const sourceBoundaryStatus = authoredRoots.length > 0
|
|
1775
|
+
? {
|
|
1776
|
+
status: 'pass',
|
|
1777
|
+
reasonCode: 'source_boundary_detected',
|
|
1778
|
+
message: `Authored roots detected: ${authoredRoots.join(', ')}.`,
|
|
1779
|
+
}
|
|
1780
|
+
: {
|
|
1781
|
+
status: 'warn',
|
|
1782
|
+
reasonCode: 'source_boundary_empty',
|
|
1783
|
+
message: 'No authored roots were detected under the canonical project surface.',
|
|
1784
|
+
};
|
|
1785
|
+
|
|
1786
|
+
let starterUtilsStatus = {
|
|
1787
|
+
status: 'info',
|
|
1788
|
+
reasonCode: 'starter_utils_not_scaffolded',
|
|
1789
|
+
message: 'No local starter-utils lane is present in this project.',
|
|
1790
|
+
};
|
|
1791
|
+
if (hasStarterUtils && hasStarterImport) {
|
|
1792
|
+
starterUtilsStatus = {
|
|
1793
|
+
status: 'pass',
|
|
1794
|
+
reasonCode: 'starter_utils_detected',
|
|
1795
|
+
message: `Starter helper lane is available at ${starterUtils.recommendedImportPath}.`,
|
|
1796
|
+
};
|
|
1797
|
+
} else if (hasStarterUtils) {
|
|
1798
|
+
starterUtilsStatus = {
|
|
1799
|
+
status: 'warn',
|
|
1800
|
+
reasonCode: 'starter_utils_entry_missing',
|
|
1801
|
+
message: 'Starter helper files exist, but src/starter-utils/index.js is missing.',
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
let starterLaneStatus = {
|
|
1806
|
+
status: 'info',
|
|
1807
|
+
reasonCode: 'starter_lane_bootstrap',
|
|
1808
|
+
message: 'This project is currently on the bootstrap-authored lane.',
|
|
1809
|
+
};
|
|
1810
|
+
if (mode === 'registry' && laneId !== 'bootstrap-authored-project') {
|
|
1811
|
+
if (hasStarterUtils && hasStarterImport) {
|
|
1812
|
+
starterLaneStatus = {
|
|
1813
|
+
status: 'pass',
|
|
1814
|
+
reasonCode: 'starter_lane_local_helpers',
|
|
1815
|
+
message: `AI paved road ${laneId} is aligned with local starter-utils imports.`,
|
|
1816
|
+
};
|
|
1817
|
+
} else if (preferredPackageSpecifier) {
|
|
1818
|
+
starterLaneStatus = {
|
|
1819
|
+
status: 'info',
|
|
1820
|
+
reasonCode: 'starter_lane_package_surface',
|
|
1821
|
+
message: `AI paved road ${laneId} currently resolves through ${preferredPackageSpecifier}.`,
|
|
1822
|
+
};
|
|
1823
|
+
} else {
|
|
1824
|
+
starterLaneStatus = {
|
|
1825
|
+
status: 'warn',
|
|
1826
|
+
reasonCode: 'starter_lane_unresolved',
|
|
1827
|
+
message: `AI paved road ${laneId} does not have a local helper lane or preferred package surface.`,
|
|
1828
|
+
};
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
return {
|
|
1833
|
+
sourceBoundary: sourceBoundaryStatus,
|
|
1834
|
+
starterUtils: starterUtilsStatus,
|
|
1835
|
+
starterLane: starterLaneStatus,
|
|
1836
|
+
};
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1352
1839
|
function toImportPath(relativePath) {
|
|
1353
1840
|
const normalized = normalizeProjectRelativePath(relativePath);
|
|
1354
1841
|
if (normalized.startsWith('.')) return normalized;
|
|
@@ -1420,6 +1907,10 @@ function normalizeExplainPayload(explained) {
|
|
|
1420
1907
|
scope: entry.scope || 'core',
|
|
1421
1908
|
}))
|
|
1422
1909
|
: [],
|
|
1910
|
+
sourceBoundary: normalizeSourceBoundary(explained.sourceBoundary),
|
|
1911
|
+
starterUtils: normalizeStarterUtils(explained.starterUtils),
|
|
1912
|
+
packs: normalizeProjectPacks(explained.packs),
|
|
1913
|
+
aiGuidance: normalizeAiGuidance(explained.aiGuidance),
|
|
1423
1914
|
};
|
|
1424
1915
|
}
|
|
1425
1916
|
|
|
@@ -1433,6 +1924,11 @@ function normalizeCheckPayload({ projectRoot, checked }) {
|
|
|
1433
1924
|
errors: Array.isArray(checked.errors) ? checked.errors : [],
|
|
1434
1925
|
warnings: Array.isArray(checked.warnings) ? checked.warnings : [],
|
|
1435
1926
|
starterContentRegistries: Array.isArray(checked.starterContentRegistries) ? checked.starterContentRegistries : [],
|
|
1927
|
+
sourceBoundary: normalizeSourceBoundary(checked.sourceBoundary),
|
|
1928
|
+
starterUtils: normalizeStarterUtils(checked.starterUtils),
|
|
1929
|
+
packs: normalizeProjectPacks(checked.packs),
|
|
1930
|
+
aiGuidance: normalizeAiGuidance(checked.aiGuidance),
|
|
1931
|
+
surfaceDrift: normalizeSurfaceDrift(checked.surfaceDrift),
|
|
1436
1932
|
};
|
|
1437
1933
|
}
|
|
1438
1934
|
|