@forgeax/engine-pack 0.1.23 → 0.1.25

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.
Files changed (157) hide show
  1. package/README.md +12 -6
  2. package/dist/build.d.ts +4 -4
  3. package/dist/build.d.ts.map +1 -1
  4. package/dist/build.mjs +390 -294
  5. package/dist/build.mjs.map +1 -1
  6. package/dist/cli-asset.mjs +33 -35
  7. package/dist/cli-asset.mjs.map +1 -1
  8. package/dist/evidence/material-cook.d.ts +26 -0
  9. package/dist/evidence/material-cook.d.ts.map +1 -1
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.mjs +121 -27
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/material-cook.d.ts +1 -1
  15. package/dist/material-cook.d.ts.map +1 -1
  16. package/dist/material-cook.mjs +102 -4
  17. package/dist/material-cook.mjs.map +1 -1
  18. package/dist/{parameterized-pack-node.d.ts → pack-authoring-node.d.ts} +7 -7
  19. package/dist/pack-authoring-node.d.ts.map +1 -0
  20. package/dist/{parameterized-pack-node.mjs → pack-authoring-node.mjs} +59 -63
  21. package/dist/pack-authoring-node.mjs.map +1 -0
  22. package/dist/{parameterized-pack.d.ts → pack-authoring.d.ts} +28 -31
  23. package/dist/pack-authoring.d.ts.map +1 -0
  24. package/dist/pack-authoring.mjs +1137 -0
  25. package/dist/pack-authoring.mjs.map +1 -0
  26. package/dist/runtime.mjs +1 -1
  27. package/dist/runtime.mjs.map +1 -1
  28. package/dist/scanner.d.ts +11 -9
  29. package/dist/scanner.d.ts.map +1 -1
  30. package/dist/scanner.mjs +36 -34
  31. package/dist/scanner.mjs.map +1 -1
  32. package/dist/schema.mjs +1 -1
  33. package/dist/schema.mjs.map +1 -1
  34. package/dist/scriptable-pack-node.d.ts +4 -4
  35. package/dist/scriptable-pack-node.d.ts.map +1 -1
  36. package/dist/scriptable-pack-node.mjs +18 -20
  37. package/dist/scriptable-pack-node.mjs.map +1 -1
  38. package/dist/scriptable-pack.d.ts +3 -2
  39. package/dist/scriptable-pack.d.ts.map +1 -1
  40. package/dist/scriptable-pack.mjs +19 -23
  41. package/dist/scriptable-pack.mjs.map +1 -1
  42. package/package.json +2 -7
  43. package/schema/pack.schema.json +1 -1
  44. package/src/__tests__/material-cook-receipt-layer-plan.unit.test.ts +16 -0
  45. package/src/__tests__/material-cook-schema.unit.test.ts +62 -0
  46. package/src/__tests__/material-declaration-boundary.unit.test.ts +35 -0
  47. package/src/__tests__/material-surface-consumer-census.test.ts +24 -0
  48. package/src/__tests__/material-surface-publication.unit.test.ts +159 -0
  49. package/src/__tests__/material-surface-wire.unit.test.ts +30 -0
  50. package/src/__tests__/{parameterized-pack-authoring-gateway.unit.test.ts → pack-authoring-gateway.unit.test.ts} +9 -9
  51. package/src/__tests__/{parameterized-pack.unit.test.ts → pack-authoring.unit.test.ts} +10 -10
  52. package/src/__tests__/{parameterized-pack-scanner.unit.test.ts → pack-scanner.unit.test.ts} +6 -6
  53. package/src/__tests__/scanner-inventory.contract.test.ts +2 -4
  54. package/src/__tests__/scanner-inventory.test.ts +7 -6
  55. package/src/__tests__/scriptable-pack-cli.integration.test.ts +1 -1
  56. package/src/build.ts +10 -8
  57. package/src/catalog-builder.ts +3 -3
  58. package/src/cli-asset.ts +5 -5
  59. package/src/evidence/material-cook.ts +170 -7
  60. package/src/evidence/source-inventory.ts +3 -3
  61. package/src/index.ts +6 -1
  62. package/src/material-cook.ts +3 -0
  63. package/src/{parameterized-pack-node.ts → pack-authoring-node.ts} +71 -73
  64. package/src/{parameterized-pack.ts → pack-authoring.ts} +59 -74
  65. package/src/scanner.ts +33 -31
  66. package/src/schema/material-cook.schema.json +47 -1
  67. package/src/scriptable-pack-node.ts +25 -25
  68. package/src/scriptable-pack.ts +3 -2
  69. package/dist/__tests__/ai-recovery.unit.test.d.ts +0 -2
  70. package/dist/__tests__/ai-recovery.unit.test.d.ts.map +0 -1
  71. package/dist/__tests__/artifact-path.test.d.ts +0 -2
  72. package/dist/__tests__/artifact-path.test.d.ts.map +0 -1
  73. package/dist/__tests__/asset-evidence-error-hints.test.d.ts +0 -2
  74. package/dist/__tests__/asset-evidence-error-hints.test.d.ts.map +0 -1
  75. package/dist/__tests__/asset-evidence-lifecycle.test.d.ts +0 -2
  76. package/dist/__tests__/asset-evidence-lifecycle.test.d.ts.map +0 -1
  77. package/dist/__tests__/asset-evidence-schema.test.d.ts +0 -2
  78. package/dist/__tests__/asset-evidence-schema.test.d.ts.map +0 -1
  79. package/dist/__tests__/atlas-cli-region-mismatch.test.d.ts +0 -2
  80. package/dist/__tests__/atlas-cli-region-mismatch.test.d.ts.map +0 -1
  81. package/dist/__tests__/atlas-error-code-owner.test-d.d.ts +0 -2
  82. package/dist/__tests__/atlas-error-code-owner.test-d.d.ts.map +0 -1
  83. package/dist/__tests__/cli-asset-evidence.integration.test.d.ts +0 -2
  84. package/dist/__tests__/cli-asset-evidence.integration.test.d.ts.map +0 -1
  85. package/dist/__tests__/cli.unit.test.d.ts +0 -2
  86. package/dist/__tests__/cli.unit.test.d.ts.map +0 -1
  87. package/dist/__tests__/evidence-source-inventory.unit.test.d.ts +0 -2
  88. package/dist/__tests__/evidence-source-inventory.unit.test.d.ts.map +0 -1
  89. package/dist/__tests__/guid-collision.unit.test.d.ts +0 -2
  90. package/dist/__tests__/guid-collision.unit.test.d.ts.map +0 -1
  91. package/dist/__tests__/guid-validator-surface.unit.test.d.ts +0 -2
  92. package/dist/__tests__/guid-validator-surface.unit.test.d.ts.map +0 -1
  93. package/dist/__tests__/inventory-schema.test.d.ts +0 -2
  94. package/dist/__tests__/inventory-schema.test.d.ts.map +0 -1
  95. package/dist/__tests__/material-cook-dependencies.unit.test.d.ts +0 -2
  96. package/dist/__tests__/material-cook-dependencies.unit.test.d.ts.map +0 -1
  97. package/dist/__tests__/material-cook-receipt.unit.test.d.ts +0 -2
  98. package/dist/__tests__/material-cook-receipt.unit.test.d.ts.map +0 -1
  99. package/dist/__tests__/material-cook-schema.unit.test.d.ts +0 -2
  100. package/dist/__tests__/material-cook-schema.unit.test.d.ts.map +0 -1
  101. package/dist/__tests__/mesh-bin-consumer-surface.unit.test.d.ts +0 -2
  102. package/dist/__tests__/mesh-bin-consumer-surface.unit.test.d.ts.map +0 -1
  103. package/dist/__tests__/mesh-bin-contract.unit.test.d.ts +0 -2
  104. package/dist/__tests__/mesh-bin-contract.unit.test.d.ts.map +0 -1
  105. package/dist/__tests__/meta-schema-optional.test.d.ts +0 -2
  106. package/dist/__tests__/meta-schema-optional.test.d.ts.map +0 -1
  107. package/dist/__tests__/meta-source-overrides.unit.test.d.ts +0 -2
  108. package/dist/__tests__/meta-source-overrides.unit.test.d.ts.map +0 -1
  109. package/dist/__tests__/native-cooker-registry.test.d.ts +0 -2
  110. package/dist/__tests__/native-cooker-registry.test.d.ts.map +0 -1
  111. package/dist/__tests__/offline-evidence-artifact-verification-owner.test-d.d.ts +0 -2
  112. package/dist/__tests__/offline-evidence-artifact-verification-owner.test-d.d.ts.map +0 -1
  113. package/dist/__tests__/offline-evidence.integration.test.d.ts +0 -2
  114. package/dist/__tests__/offline-evidence.integration.test.d.ts.map +0 -1
  115. package/dist/__tests__/owner-chain.integration.test.d.ts +0 -2
  116. package/dist/__tests__/owner-chain.integration.test.d.ts.map +0 -1
  117. package/dist/__tests__/pack-v2-fixture-migration.test.d.ts +0 -2
  118. package/dist/__tests__/pack-v2-fixture-migration.test.d.ts.map +0 -1
  119. package/dist/__tests__/pack-v2-schema.test.d.ts +0 -2
  120. package/dist/__tests__/pack-v2-schema.test.d.ts.map +0 -1
  121. package/dist/__tests__/pack.unit.test.d.ts +0 -2
  122. package/dist/__tests__/pack.unit.test.d.ts.map +0 -1
  123. package/dist/__tests__/package-finalizer.contract.test.d.ts +0 -2
  124. package/dist/__tests__/package-finalizer.contract.test.d.ts.map +0 -1
  125. package/dist/__tests__/parameterized-pack-authoring-gateway.unit.test.d.ts +0 -2
  126. package/dist/__tests__/parameterized-pack-authoring-gateway.unit.test.d.ts.map +0 -1
  127. package/dist/__tests__/parameterized-pack-scanner.unit.test.d.ts +0 -2
  128. package/dist/__tests__/parameterized-pack-scanner.unit.test.d.ts.map +0 -1
  129. package/dist/__tests__/parameterized-pack.unit.test.d.ts +0 -2
  130. package/dist/__tests__/parameterized-pack.unit.test.d.ts.map +0 -1
  131. package/dist/__tests__/producer-contract-schema.unit.test.d.ts +0 -2
  132. package/dist/__tests__/producer-contract-schema.unit.test.d.ts.map +0 -1
  133. package/dist/__tests__/resolve-asset-source.test.d.ts +0 -2
  134. package/dist/__tests__/resolve-asset-source.test.d.ts.map +0 -1
  135. package/dist/__tests__/runtime-projection.unit.test.d.ts +0 -2
  136. package/dist/__tests__/runtime-projection.unit.test.d.ts.map +0 -1
  137. package/dist/__tests__/runtime.browser.test.d.ts +0 -2
  138. package/dist/__tests__/runtime.browser.test.d.ts.map +0 -1
  139. package/dist/__tests__/scanner-blacklist.test.d.ts +0 -2
  140. package/dist/__tests__/scanner-blacklist.test.d.ts.map +0 -1
  141. package/dist/__tests__/scanner-inventory.contract.test.d.ts +0 -2
  142. package/dist/__tests__/scanner-inventory.contract.test.d.ts.map +0 -1
  143. package/dist/__tests__/scanner-inventory.test.d.ts +0 -2
  144. package/dist/__tests__/scanner-inventory.test.d.ts.map +0 -1
  145. package/dist/__tests__/scanner-mount-cycle.test.d.ts +0 -2
  146. package/dist/__tests__/scanner-mount-cycle.test.d.ts.map +0 -1
  147. package/dist/__tests__/scriptable-pack-cli.integration.test.d.ts +0 -2
  148. package/dist/__tests__/scriptable-pack-cli.integration.test.d.ts.map +0 -1
  149. package/dist/__tests__/scriptable-pack-ddc-key.unit.test.d.ts +0 -2
  150. package/dist/__tests__/scriptable-pack-ddc-key.unit.test.d.ts.map +0 -1
  151. package/dist/__tests__/topology-actions.unit.test.d.ts +0 -2
  152. package/dist/__tests__/topology-actions.unit.test.d.ts.map +0 -1
  153. package/dist/__tests__/topology.unit.test.d.ts +0 -2
  154. package/dist/__tests__/topology.unit.test.d.ts.map +0 -1
  155. package/dist/parameterized-pack-node.d.ts.map +0 -1
  156. package/dist/parameterized-pack-node.mjs.map +0 -1
  157. package/dist/parameterized-pack.d.ts.map +0 -1
@@ -100,7 +100,7 @@ export type PackAuthoringErrorCode =
100
100
  | 'pack-guid-collision'
101
101
  | 'pack-parent-not-found'
102
102
  | 'pack-parent-cycle'
103
- | 'pack-parent-not-parameterized'
103
+ | 'pack-parent-has-no-parameters'
104
104
  | 'pack-parameter-invalid'
105
105
  | 'pack-content-dependency-stalled'
106
106
  | 'pack-output-reference-missing'
@@ -601,7 +601,7 @@ interface PackDefinitionBase {
601
601
  readonly sceneComponents?: readonly ScriptablePackSceneComponentInput[];
602
602
  }
603
603
 
604
- export type ParameterizedPackDefinition<
604
+ export type ScriptablePackDefinition<
605
605
  TParameters extends readonly PackParameterDefinition[] | undefined = undefined,
606
606
  > = PackDefinitionBase &
607
607
  (TParameters extends readonly PackParameterDefinition[]
@@ -613,17 +613,13 @@ export type ParameterizedPackDefinition<
613
613
  readonly build: (context: PackBuildContextWithoutParameters) => PackBuildResult;
614
614
  });
615
615
 
616
- export type PackDefinition =
617
- | ParameterizedPackDefinition<undefined>
618
- | ParameterizedPackDefinition<readonly [PackParameterDefinition, ...PackParameterDefinition[]]>;
619
-
620
616
  export type PackParameterList = readonly [PackParameterDefinition, ...PackParameterDefinition[]];
621
617
  type NonEmptyParameters = PackParameterList;
622
618
  type NoParameterPackInput = PackDefinitionBase & {
623
619
  readonly parameters?: never;
624
620
  readonly build: (context: PackBuildContextWithoutParameters) => PackBuildResult;
625
621
  };
626
- type ParameterizedPackInput<TParameters extends NonEmptyParameters> = PackDefinitionBase & {
622
+ type ScriptablePackDefinitionInput<TParameters extends NonEmptyParameters> = PackDefinitionBase & {
627
623
  readonly parameters: TParameters;
628
624
  readonly build: (context: PackBuildContextWithParameters<TParameters>) => PackBuildResult;
629
625
  };
@@ -646,10 +642,8 @@ export function definePackageId(value: string | PackageId): PackageId {
646
642
  }
647
643
 
648
644
  function cloneDefinition(
649
- definition:
650
- | ParameterizedPackDefinition<NonEmptyParameters>
651
- | ParameterizedPackDefinition<undefined>,
652
- ): ParameterizedPackDefinition<NonEmptyParameters> | ParameterizedPackDefinition<undefined> {
645
+ definition: ScriptablePackDefinition<NonEmptyParameters> | ScriptablePackDefinition<undefined>,
646
+ ): ScriptablePackDefinition<NonEmptyParameters> | ScriptablePackDefinition<undefined> {
653
647
  const parameters =
654
648
  'parameters' in definition
655
649
  ? Object.freeze(
@@ -680,52 +674,50 @@ function cloneDefinition(
680
674
  packageId: definition.packageId.slice() as PackageId,
681
675
  ...(parameters === undefined ? {} : { parameters }),
682
676
  ...(sceneComponents === undefined ? {} : { sceneComponents }),
683
- }) as ParameterizedPackDefinition<NonEmptyParameters> | ParameterizedPackDefinition<undefined>;
677
+ }) as ScriptablePackDefinition<NonEmptyParameters> | ScriptablePackDefinition<undefined>;
684
678
  }
685
679
 
686
680
  /**
687
681
  * Define the only executable authoring shape. A missing `parameters` property
688
682
  * is meaningful: its build context has no `values` member.
689
683
  */
690
- export function definePack(
691
- definition: NoParameterPackInput,
692
- ): ParameterizedPackDefinition<undefined>;
684
+ export function definePack(definition: NoParameterPackInput): ScriptablePackDefinition<undefined>;
693
685
  export function definePack<const TParameters extends NonEmptyParameters>(
694
- definition: ParameterizedPackInput<TParameters>,
695
- ): ParameterizedPackDefinition<TParameters>;
686
+ definition: ScriptablePackDefinitionInput<TParameters>,
687
+ ): ScriptablePackDefinition<TParameters>;
696
688
  export function definePack(
697
- definition: NoParameterPackInput | ParameterizedPackInput<NonEmptyParameters>,
698
- ): ParameterizedPackDefinition<NonEmptyParameters> | ParameterizedPackDefinition<undefined> {
689
+ definition: NoParameterPackInput | ScriptablePackDefinitionInput<NonEmptyParameters>,
690
+ ): ScriptablePackDefinition<NonEmptyParameters> | ScriptablePackDefinition<undefined> {
699
691
  const validated = validatePackDefinition(definition);
700
692
  if (!validated.ok) throw Object.assign(new TypeError(validated.error.hint), validated.error);
701
693
  return cloneDefinition(
702
694
  validated.value as
703
- | ParameterizedPackDefinition<NonEmptyParameters>
704
- | ParameterizedPackDefinition<undefined>,
695
+ | ScriptablePackDefinition<NonEmptyParameters>
696
+ | ScriptablePackDefinition<undefined>,
705
697
  );
706
698
  }
707
699
 
708
700
  /** Union used only at orchestration boundaries that accept either source form. */
709
- export type AnyParameterizedPackDefinition =
710
- | ParameterizedPackDefinition<PackParameterList>
711
- | ParameterizedPackDefinition<undefined>;
701
+ export type AnyScriptablePackDefinition =
702
+ | ScriptablePackDefinition<PackParameterList>
703
+ | ScriptablePackDefinition<undefined>;
712
704
 
713
- export interface ParameterizedPackSourceMeta {
705
+ export interface ScriptablePackSourceMeta {
714
706
  readonly schemaVersion: '2.0.0';
715
- readonly kind: 'parameterized-pack-source';
707
+ readonly kind: 'scriptable-pack-source';
716
708
  readonly packageId: string;
717
709
  readonly source: string;
718
710
  readonly parameters?: readonly Readonly<Record<string, unknown>>[];
719
711
  }
720
712
 
721
713
  /** Ephemeral scan evidence; it intentionally contains no output GUID table. */
722
- export function projectParameterizedPackMeta(
723
- definition: AnyParameterizedPackDefinition,
714
+ export function projectScriptablePackMeta(
715
+ definition: AnyScriptablePackDefinition,
724
716
  sourcePath: string,
725
- ): ParameterizedPackSourceMeta {
717
+ ): ScriptablePackSourceMeta {
726
718
  return {
727
719
  schemaVersion: '2.0.0',
728
- kind: 'parameterized-pack-source',
720
+ kind: 'scriptable-pack-source',
729
721
  packageId: PackageId.format(definition.packageId),
730
722
  source: sourcePath,
731
723
  ...('parameters' in definition
@@ -753,7 +745,7 @@ export function validatePackDefinition(
753
745
  value: unknown,
754
746
  sourcePath?: string,
755
747
  ): Result<
756
- ParameterizedPackDefinition<NonEmptyParameters> | ParameterizedPackDefinition<undefined>,
748
+ ScriptablePackDefinition<NonEmptyParameters> | ScriptablePackDefinition<undefined>,
757
749
  PackAuthoringError
758
750
  > {
759
751
  if (!isRecord(value))
@@ -818,7 +810,7 @@ export function validatePackDefinition(
818
810
  ...(value.name === undefined ? {} : { name: value.name }),
819
811
  ...(sceneComponents.value === undefined ? {} : { sceneComponents: sceneComponents.value }),
820
812
  build: value.build,
821
- }) as ParameterizedPackDefinition<undefined>,
813
+ }) as ScriptablePackDefinition<undefined>,
822
814
  );
823
815
  }
824
816
  const parameters = validateParameterDefinitions(value.parameters);
@@ -831,19 +823,19 @@ export function validatePackDefinition(
831
823
  ...(sceneComponents.value === undefined ? {} : { sceneComponents: sceneComponents.value }),
832
824
  parameters: parameters.value,
833
825
  build: value.build,
834
- }) as ParameterizedPackDefinition<NonEmptyParameters>,
826
+ }) as ScriptablePackDefinition<NonEmptyParameters>,
835
827
  );
836
828
  }
837
829
 
838
- export function isParameterizedPack(
839
- value: ParameterizedPackDefinition | unknown,
840
- ): value is ParameterizedPackDefinition<NonEmptyParameters> {
830
+ export function hasPackParameters(
831
+ value: ScriptablePackDefinition | unknown,
832
+ ): value is ScriptablePackDefinition<NonEmptyParameters> {
841
833
  return isRecord(value) && Array.isArray(value.parameters) && value.parameters.length > 0;
842
834
  }
843
835
 
844
836
  /** Resolve defaults plus a sparse instance override with shallow replacement. */
845
837
  export function resolvePackParameterValues(
846
- definition: ParameterizedPackDefinition<NonEmptyParameters>,
838
+ definition: ScriptablePackDefinition<NonEmptyParameters>,
847
839
  overrides: unknown = {},
848
840
  inheritedValues?: Readonly<Record<string, PackParameterValue>>,
849
841
  ): Result<PackParameterValues<NonEmptyParameters>, PackAuthoringError> {
@@ -1045,9 +1037,7 @@ function parsePackJsonAsset(
1045
1037
  }
1046
1038
 
1047
1039
  /** Parse the two mutually exclusive v3 pack.json branches. */
1048
- export function parseParameterizedPackJson(
1049
- value: unknown,
1050
- ): Result<ParsedPackJson, PackAuthoringError> {
1040
+ export function parsePackSourceJson(value: unknown): Result<ParsedPackJson, PackAuthoringError> {
1051
1041
  if (!isRecord(value))
1052
1042
  return jsonError('$', 'a v3 pack.json object', value, 'document is not an object');
1053
1043
  if (value.schemaVersion !== '3.0.0')
@@ -1127,9 +1117,6 @@ export function parseParameterizedPackJson(
1127
1117
  });
1128
1118
  }
1129
1119
 
1130
- export const parsePackJson = parseParameterizedPackJson;
1131
- export const parsePackAuthoringJson = parseParameterizedPackJson;
1132
-
1133
1120
  export interface DirectPackAssetProjection extends DirectPackJsonAsset {
1134
1121
  readonly guid: string;
1135
1122
  readonly sourceKey: string;
@@ -1144,7 +1131,7 @@ export interface DirectPackProjection {
1144
1131
  export function projectDirectPackJson(
1145
1132
  value: ParsedDirectPackJson | DirectPackJson,
1146
1133
  ): Result<DirectPackProjection, PackAuthoringError> {
1147
- const parsed = 'format' in value ? ok(value) : parseParameterizedPackJson(value);
1134
+ const parsed = 'format' in value ? ok(value) : parsePackSourceJson(value);
1148
1135
  if (!parsed.ok) return parsed;
1149
1136
  if (parsed.value.format !== 'direct') {
1150
1137
  return failure(
@@ -1238,9 +1225,9 @@ export async function resolvePackParameterInheritance(
1238
1225
  if (current.format === 'direct') {
1239
1226
  return failure(
1240
1227
  authoringError(
1241
- 'pack-parent-not-parameterized',
1242
- 'a parameterized Pack source as the parent',
1243
- 'direct packs cannot be instance parents; point the instance at a parameterized source',
1228
+ 'pack-parent-has-no-parameters',
1229
+ 'a ScriptablePack source with parameters as the parent',
1230
+ 'direct packs cannot be instance parents; point the instance at a ScriptablePack source with parameters',
1244
1231
  { packageId: currentId },
1245
1232
  ),
1246
1233
  );
@@ -1251,7 +1238,7 @@ export async function resolvePackParameterInheritance(
1251
1238
  if (descriptors.value.length === 0) {
1252
1239
  return failure(
1253
1240
  authoringError(
1254
- 'pack-parent-not-parameterized',
1241
+ 'pack-parent-has-no-parameters',
1255
1242
  'the parent source to declare a non-empty parameter list',
1256
1243
  'use clone for an independent zero-parameter Pack instead of creating an empty instance',
1257
1244
  { packageId: currentId },
@@ -1263,7 +1250,7 @@ export async function resolvePackParameterInheritance(
1263
1250
  packageId: current.packageId,
1264
1251
  parameters: descriptors.value as NonEmptyParameters,
1265
1252
  build: () => ok({}),
1266
- } as ParameterizedPackDefinition<NonEmptyParameters>;
1253
+ } as ScriptablePackDefinition<NonEmptyParameters>;
1267
1254
  const values = resolvePackParameterValues(definition);
1268
1255
  if (!values.ok) return values;
1269
1256
  return ok({
@@ -1280,7 +1267,7 @@ export async function resolvePackParameterInheritance(
1280
1267
  authoringError(
1281
1268
  'pack-parent-not-found',
1282
1269
  'the parent packageId to resolve in the source index',
1283
- 'inspect the parent locator or recreate the instance from a live parameterized Pack',
1270
+ 'inspect the parent locator or recreate the instance from a live ScriptablePack with parameters',
1284
1271
  { packageId: currentId, parent: PackageId.format(current.parent) },
1285
1272
  ),
1286
1273
  );
@@ -1310,7 +1297,7 @@ export async function resolvePackParameterInheritance(
1310
1297
  packageId: resolvedParent.value.rootPackageId,
1311
1298
  parameters: descriptors as NonEmptyParameters,
1312
1299
  build: () => ok({}),
1313
- } as ParameterizedPackDefinition<NonEmptyParameters>;
1300
+ } as ScriptablePackDefinition<NonEmptyParameters>;
1314
1301
  const values = resolvePackParameterValues(
1315
1302
  definition,
1316
1303
  current.values,
@@ -1331,7 +1318,7 @@ export async function resolvePackParameterInheritance(
1331
1318
 
1332
1319
  export const resolvePackInheritance = resolvePackParameterInheritance;
1333
1320
 
1334
- export const PARAMETERIZED_PACK_OPERATION_IDS = [
1321
+ export const PACK_AUTHORING_OPERATION_IDS = [
1335
1322
  'asset.list',
1336
1323
  'asset.inspect',
1337
1324
  'asset.resolve',
@@ -1344,12 +1331,12 @@ export const PARAMETERIZED_PACK_OPERATION_IDS = [
1344
1331
  'asset-source.cold-cook',
1345
1332
  ] as const;
1346
1333
 
1347
- export type ParameterizedPackOperationId = (typeof PARAMETERIZED_PACK_OPERATION_IDS)[number];
1334
+ export type PackAuthoringOperationId = (typeof PACK_AUTHORING_OPERATION_IDS)[number];
1348
1335
 
1349
- export interface ParameterizedPackOperation {
1336
+ export interface PackAuthoringOperation {
1350
1337
  readonly requestId: string;
1351
1338
  readonly expectedRevision?: string;
1352
- readonly operation: ParameterizedPackOperationId;
1339
+ readonly operation: PackAuthoringOperationId;
1353
1340
  readonly subject?: string;
1354
1341
  readonly sourcePath?: string;
1355
1342
  readonly targetPath?: string;
@@ -1370,10 +1357,10 @@ export interface ParameterizedPackOperation {
1370
1357
  readonly require?: 'identity' | 'present' | 'ready';
1371
1358
  }
1372
1359
 
1373
- export type ParameterizedPackResolutionStatus = 'identity' | 'present' | 'ready';
1360
+ export type PackAuthoringResolutionStatus = 'identity' | 'present' | 'ready';
1374
1361
 
1375
- export interface ParameterizedPackOperationResult {
1376
- readonly operation: ParameterizedPackOperationId;
1362
+ export interface PackAuthoringOperationResult {
1363
+ readonly operation: PackAuthoringOperationId;
1377
1364
  readonly requestId: string;
1378
1365
  readonly sourcePath?: string;
1379
1366
  readonly targetPath?: string;
@@ -1383,7 +1370,7 @@ export interface ParameterizedPackOperationResult {
1383
1370
  readonly sourceKey?: string;
1384
1371
  readonly guid?: string;
1385
1372
  readonly format?: 'pack.ts' | 'pack.json' | 'direct' | 'instance';
1386
- readonly status?: ParameterizedPackResolutionStatus;
1373
+ readonly status?: PackAuthoringResolutionStatus;
1387
1374
  readonly kind?: string;
1388
1375
  readonly parameters?: readonly Readonly<Record<string, unknown>>[];
1389
1376
  readonly values?: Readonly<Record<string, unknown>>;
@@ -1391,21 +1378,21 @@ export interface ParameterizedPackOperationResult {
1391
1378
  readonly parentChain?: readonly string[];
1392
1379
  readonly assets?: readonly Readonly<Record<string, unknown>>[];
1393
1380
  readonly sources?: readonly Readonly<Record<string, unknown>>[];
1394
- readonly capabilities?: readonly ParameterizedPackOperationId[];
1381
+ readonly capabilities?: readonly PackAuthoringOperationId[];
1395
1382
  readonly snapshot?: {
1396
1383
  readonly sourceCount: number;
1397
1384
  readonly assetCount: number;
1398
1385
  };
1399
1386
  }
1400
1387
 
1401
- export interface ParameterizedPackGatewayPort<TResult = unknown> {
1402
- execute(operation: ParameterizedPackOperation): Promise<Result<TResult, PackAuthoringError>>;
1388
+ export interface PackAuthoringGatewayPort<TResult = unknown> {
1389
+ execute(operation: PackAuthoringOperation): Promise<Result<TResult, PackAuthoringError>>;
1403
1390
  }
1404
1391
 
1405
1392
  /** One idempotent gateway wrapper shared by Editor and CLI adapters. */
1406
- export function createParameterizedPackAuthoringGateway<TResult = unknown>(
1407
- port: ParameterizedPackGatewayPort<TResult>,
1408
- ): ParameterizedPackGatewayPort<TResult> {
1393
+ export function createPackAuthoringGateway<TResult = unknown>(
1394
+ port: PackAuthoringGatewayPort<TResult>,
1395
+ ): PackAuthoringGatewayPort<TResult> {
1409
1396
  const requests = new Map<
1410
1397
  string,
1411
1398
  { fingerprint: string; result: Promise<Result<TResult, PackAuthoringError>> }
@@ -1478,15 +1465,13 @@ export function createParameterizedPackAuthoringGateway<TResult = unknown>(
1478
1465
  };
1479
1466
  }
1480
1467
 
1481
- export const PARAMETERIZED_PACK_OPERATION_DESCRIPTORS = PARAMETERIZED_PACK_OPERATION_IDS.map(
1482
- (id) => ({
1483
- id,
1484
- domain: id.startsWith('asset-source.') ? 'session' : 'asset',
1485
- readOnly: id.startsWith('asset.'),
1486
- requiresRevision: !id.startsWith('asset.') && id !== 'asset-source.create',
1487
- }),
1488
- ) as readonly {
1489
- id: ParameterizedPackOperationId;
1468
+ export const PACK_AUTHORING_OPERATION_DESCRIPTORS = PACK_AUTHORING_OPERATION_IDS.map((id) => ({
1469
+ id,
1470
+ domain: id.startsWith('asset-source.') ? 'session' : 'asset',
1471
+ readOnly: id.startsWith('asset.'),
1472
+ requiresRevision: !id.startsWith('asset.') && id !== 'asset-source.create',
1473
+ })) as readonly {
1474
+ id: PackAuthoringOperationId;
1490
1475
  domain: 'asset' | 'session';
1491
1476
  readOnly: boolean;
1492
1477
  requiresRevision: boolean;
package/src/scanner.ts CHANGED
@@ -12,19 +12,19 @@ import { PACK_ERROR_HINTS } from '@forgeax/engine-types';
12
12
  import { PackError } from './errors.js';
13
13
  import { isValidAssetGuidString, PackageId } from './guid.js';
14
14
  import {
15
- type AnyParameterizedPackDefinition,
16
- type ParameterizedPackSourceMeta,
17
- parseParameterizedPackJson,
15
+ type AnyScriptablePackDefinition,
16
+ parsePackSourceJson,
18
17
  projectDirectPackJson,
19
- projectParameterizedPackMeta,
20
- } from './parameterized-pack.js';
18
+ projectScriptablePackMeta,
19
+ type ScriptablePackSourceMeta,
20
+ } from './pack-authoring.js';
21
21
  import { validateProducerContract, validateProducerOutputs } from './producer-contract.js';
22
22
  import { resolveAssetSource } from './resolve-asset-source.js';
23
23
  import { validateMeta, validatePack } from './schema-compiled.js';
24
24
  import type { ScriptablePackSourceClosureEntry } from './scriptable-pack.js';
25
25
  import {
26
26
  inventoryScriptablePackSource,
27
- loadParameterizedScriptablePack,
27
+ loadScriptablePack,
28
28
  type ScriptablePackModuleExecutor,
29
29
  } from './scriptable-pack-node.js';
30
30
 
@@ -62,9 +62,13 @@ export interface ScriptablePackScanOptions {
62
62
  }
63
63
 
64
64
  /** Stable default policy shared by inventory and production owners. */
65
- export const STANDARD_SCRIPTABLE_PACK_SCAN_OPTIONS = Object.freeze(
66
- {},
67
- ) satisfies ScriptablePackScanOptions;
65
+ export const STANDARD_SCRIPTABLE_PACK_SCAN_OPTIONS = Object.freeze({
66
+ // Scriptable Packs execute in an isolated worker. A cold worker must
67
+ // compile the authored source closure before it can return metadata;
68
+ // heavy procedural packs otherwise make the shared catalog fall back to
69
+ // an empty degraded projection at the old 15-second budget.
70
+ timeoutMs: 60_000,
71
+ }) satisfies ScriptablePackScanOptions;
68
72
 
69
73
  export interface InventoryDeclaration {
70
74
  readonly guid: string;
@@ -85,8 +89,8 @@ export interface ScanInventory {
85
89
  export interface ScriptablePackInventoryDeclaration {
86
90
  readonly sourcePath: string;
87
91
  readonly sourceRevision: string;
88
- readonly meta: ParameterizedPackSourceMeta;
89
- readonly definition: Readonly<AnyParameterizedPackDefinition>;
92
+ readonly meta: ScriptablePackSourceMeta;
93
+ readonly definition: Readonly<AnyScriptablePackDefinition>;
90
94
  readonly sourceClosure: readonly ScriptablePackSourceClosureEntry[];
91
95
  }
92
96
 
@@ -125,7 +129,7 @@ export interface LegacyPackInventoryDocument {
125
129
  readonly assets: readonly PackInventoryAsset[];
126
130
  }
127
131
 
128
- export interface ParameterizedPackInventoryDocument {
132
+ export interface PackSourceInventoryDocument {
129
133
  readonly schemaVersion: '3.0.0';
130
134
  readonly packageId: string;
131
135
  readonly assets?: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
@@ -133,9 +137,7 @@ export interface ParameterizedPackInventoryDocument {
133
137
  readonly values?: Readonly<Record<string, unknown>>;
134
138
  }
135
139
 
136
- export type PackInventoryDocument =
137
- | LegacyPackInventoryDocument
138
- | ParameterizedPackInventoryDocument;
140
+ export type PackInventoryDocument = LegacyPackInventoryDocument | PackSourceInventoryDocument;
139
141
 
140
142
  export interface PackInventoryAsset {
141
143
  readonly guid: string;
@@ -164,11 +166,11 @@ export type ScanSourceDeclaration =
164
166
  readonly value: PackInventoryDocument;
165
167
  }
166
168
  | {
167
- readonly format: 'pack.ts-parameterized';
169
+ readonly format: 'pack.ts';
168
170
  readonly sourcePath: string;
169
171
  readonly sourceRevision: string;
170
- readonly value: ParameterizedPackSourceMeta;
171
- readonly definition: AnyParameterizedPackDefinition;
172
+ readonly value: ScriptablePackSourceMeta;
173
+ readonly definition: AnyScriptablePackDefinition;
172
174
  readonly sourceClosure: readonly ScriptablePackSourceClosureEntry[];
173
175
  };
174
176
 
@@ -370,7 +372,7 @@ async function scanValidated(
370
372
  const guidToPath = new Map<string, string>();
371
373
  const packRefs = new Map<string, string[]>(); // guid -> refs[]
372
374
  const packageIdToPath = new Map<string, string>();
373
- const packageKind = new Map<string, 'legacy' | 'direct' | 'instance' | 'parameterized'>();
375
+ const packageKind = new Map<string, 'legacy' | 'direct' | 'instance' | 'scriptable'>();
374
376
  const instanceParents: {
375
377
  readonly path: string;
376
378
  readonly packageId: string;
@@ -380,7 +382,7 @@ async function scanValidated(
380
382
  function registerPackage(
381
383
  packageId: string | undefined,
382
384
  path: string,
383
- kind: 'legacy' | 'direct' | 'instance' | 'parameterized',
385
+ kind: 'legacy' | 'direct' | 'instance' | 'scriptable',
384
386
  ): PackError | undefined {
385
387
  if (packageId === undefined) return undefined;
386
388
  const normalized = packageId.toLowerCase();
@@ -402,7 +404,7 @@ async function scanValidated(
402
404
  const { raw, parsed } = loaded.value;
403
405
 
404
406
  if (record(parsed) && parsed.schemaVersion === '3.0.0') {
405
- const authoring = parseParameterizedPackJson(parsed);
407
+ const authoring = parsePackSourceJson(parsed);
406
408
  if (!authoring.ok) {
407
409
  return packErr(
408
410
  makePackError('pack-malformed-pack', {
@@ -457,7 +459,7 @@ async function scanValidated(
457
459
  sourcePath: packPath,
458
460
  sourceRevision: `sha256:${createHash('sha256').update(raw).digest('hex')}`,
459
461
  sourceText: raw,
460
- value: parsed as unknown as ParameterizedPackInventoryDocument,
462
+ value: parsed as unknown as PackSourceInventoryDocument,
461
463
  });
462
464
  continue;
463
465
  }
@@ -662,7 +664,7 @@ async function scanValidated(
662
664
  }
663
665
  }
664
666
 
665
- // Parameterized source identity enters the package registry. Its outputs are
667
+ // ScriptablePack source identity enters the package registry. Its outputs are
666
668
  // intentionally absent until the dynamic build worklist evaluates it.
667
669
  for (const sourcePath of scriptablePaths) {
668
670
  let source: string;
@@ -680,7 +682,7 @@ async function scanValidated(
680
682
  ...(opts.scriptablePack ?? {}),
681
683
  ...(capture === undefined ? { metadataOnly: true } : {}),
682
684
  };
683
- const loaded = await loadParameterizedScriptablePack(sourcePath, loaderOptions);
685
+ const loaded = await loadScriptablePack(sourcePath, loaderOptions);
684
686
  if (!loaded.ok) {
685
687
  const diagnostic = loaded.error.detail.diagnostic;
686
688
  return packErr(
@@ -712,12 +714,12 @@ async function scanValidated(
712
714
  const packageCollision = registerPackage(
713
715
  PackageId.format(loaded.value.packageId),
714
716
  sourcePath,
715
- 'parameterized',
717
+ 'scriptable',
716
718
  );
717
719
  if (packageCollision !== undefined) return packErr(packageCollision);
718
- const meta = projectParameterizedPackMeta(loaded.value, sourcePath);
720
+ const meta = projectScriptablePackMeta(loaded.value, sourcePath);
719
721
  capture?.declarations.set(sourcePath, {
720
- format: 'pack.ts-parameterized',
722
+ format: 'pack.ts',
721
723
  sourcePath,
722
724
  sourceRevision: `sha256:${createHash('sha256').update(source).digest('hex')}`,
723
725
  value: meta,
@@ -749,15 +751,15 @@ async function scanValidated(
749
751
  );
750
752
  }
751
753
  const kind = packageKind.get(parentId);
752
- if (kind !== 'parameterized' && kind !== 'instance') {
754
+ if (kind !== 'scriptable' && kind !== 'instance') {
753
755
  return packErr(
754
756
  makePackError('pack-malformed-pack', {
755
757
  path: instance.path,
756
- reason: 'pack-parent-not-parameterized',
758
+ reason: 'pack-parent-has-no-parameters',
757
759
  ajvErrors: [
758
760
  {
759
761
  instancePath: '/parent',
760
- message: `parent ${instance.parent} is not a parameterized Pack`,
762
+ message: `parent ${instance.parent} is not a ScriptablePack source with parameters`,
761
763
  },
762
764
  ],
763
765
  }),
@@ -849,7 +851,7 @@ export async function scanInventory(
849
851
  const declaration = declarations.get(sourcePath);
850
852
  if (declaration?.format !== 'pack.json') continue;
851
853
  if (declaration.value.schemaVersion === '3.0.0') {
852
- const parsed = parseParameterizedPackJson(declaration.value);
854
+ const parsed = parsePackSourceJson(declaration.value);
853
855
  if (!parsed.ok) {
854
856
  return packErr(
855
857
  makePackError('pack-malformed-pack', {
@@ -9,6 +9,49 @@
9
9
  "materialGuid": { "type": "string", "minLength": 1 },
10
10
  "publicationGeneration": { "type": "integer", "minimum": 1 },
11
11
  "specializationKey": { "type": "string", "minLength": 1 },
12
+ "variantContext": {
13
+ "type": "object",
14
+ "required": ["backend", "capability"],
15
+ "properties": {
16
+ "backend": { "enum": ["webgpu", "webgl2", "wgpu-native"] },
17
+ "capability": { "enum": ["storage-buffer", "uniform-fallback"] }
18
+ },
19
+ "additionalProperties": false
20
+ },
21
+ "variants": {
22
+ "type": "array",
23
+ "items": {
24
+ "type": "object",
25
+ "required": ["context", "specializationKey", "artifact"],
26
+ "properties": {
27
+ "context": {
28
+ "type": "object",
29
+ "required": ["backend", "capability"],
30
+ "properties": {
31
+ "backend": { "enum": ["webgpu", "webgl2", "wgpu-native"] },
32
+ "capability": { "enum": ["storage-buffer", "uniform-fallback"] }
33
+ },
34
+ "additionalProperties": false
35
+ },
36
+ "specializationKey": { "type": "string", "minLength": 1 },
37
+ "artifact": {
38
+ "type": "object",
39
+ "required": ["mediaType", "path", "digest", "bytes"],
40
+ "properties": {
41
+ "mediaType": { "type": "string" },
42
+ "path": { "type": "string" },
43
+ "digest": { "type": "string", "pattern": "^sha256:" },
44
+ "bytes": {
45
+ "type": "array",
46
+ "items": { "type": "integer", "minimum": 0, "maximum": 255 }
47
+ }
48
+ },
49
+ "additionalProperties": false
50
+ }
51
+ },
52
+ "additionalProperties": false
53
+ }
54
+ },
12
55
  "artifactDigest": { "type": "string", "pattern": "^sha256:" },
13
56
  "sourceClosure": { "type": "array", "items": { "type": "string" } },
14
57
  "parameterContract": {
@@ -107,7 +150,10 @@
107
150
  "derivedInterface": {
108
151
  "type": "object",
109
152
  "required": ["layoutIdentity"],
110
- "properties": { "layoutIdentity": { "type": "string", "minLength": 1 } },
153
+ "properties": {
154
+ "layoutIdentity": { "type": "string", "minLength": 1 },
155
+ "layerPlanIdentity": { "type": "string", "minLength": 1 }
156
+ },
111
157
  "additionalProperties": false
112
158
  },
113
159
  "publicationGeneration": { "type": "integer", "minimum": 1 }