@aura3d/cli 3.0.1 → 4.0.0

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 (376) hide show
  1. package/README.md +2 -2
  2. package/dist/admission/artDirection.d.ts +28 -0
  3. package/dist/admission/artDirection.d.ts.map +1 -0
  4. package/dist/admission/artDirection.js +47 -0
  5. package/dist/admission/artDirection.js.map +1 -0
  6. package/dist/admission/audio.d.ts +19 -0
  7. package/dist/admission/audio.d.ts.map +1 -0
  8. package/dist/admission/audio.js +31 -0
  9. package/dist/admission/audio.js.map +1 -0
  10. package/dist/admission/builder-patterns.d.ts +25 -0
  11. package/dist/admission/builder-patterns.d.ts.map +1 -0
  12. package/dist/admission/builder-patterns.js +40 -0
  13. package/dist/admission/builder-patterns.js.map +1 -0
  14. package/dist/admission/gates.d.ts +136 -0
  15. package/dist/admission/gates.d.ts.map +1 -0
  16. package/dist/admission/gates.js +335 -0
  17. package/dist/admission/gates.js.map +1 -0
  18. package/dist/admission/glb.d.ts +64 -0
  19. package/dist/admission/glb.d.ts.map +1 -0
  20. package/dist/admission/glb.js +128 -0
  21. package/dist/admission/glb.js.map +1 -0
  22. package/dist/admission/index.d.ts +8 -0
  23. package/dist/admission/index.d.ts.map +1 -0
  24. package/dist/admission/index.js +8 -0
  25. package/dist/admission/index.js.map +1 -0
  26. package/dist/admission/profiles.d.ts +52 -0
  27. package/dist/admission/profiles.d.ts.map +1 -0
  28. package/dist/admission/profiles.js +91 -0
  29. package/dist/admission/profiles.js.map +1 -0
  30. package/dist/admission/qrFlags.d.ts +12 -0
  31. package/dist/admission/qrFlags.d.ts.map +1 -0
  32. package/dist/admission/qrFlags.js +48 -0
  33. package/dist/admission/qrFlags.js.map +1 -0
  34. package/dist/admission/routeGates.d.ts +36 -0
  35. package/dist/admission/routeGates.d.ts.map +1 -0
  36. package/dist/admission/routeGates.js +144 -0
  37. package/dist/admission/routeGates.js.map +1 -0
  38. package/dist/admission/texel.d.ts +50 -0
  39. package/dist/admission/texel.d.ts.map +1 -0
  40. package/dist/admission/texel.js +177 -0
  41. package/dist/admission/texel.js.map +1 -0
  42. package/dist/admission/textureStats.d.ts +45 -0
  43. package/dist/admission/textureStats.d.ts.map +1 -0
  44. package/dist/admission/textureStats.js +201 -0
  45. package/dist/admission/textureStats.js.map +1 -0
  46. package/dist/animation-asset-validator.d.ts +44 -0
  47. package/dist/animation-asset-validator.d.ts.map +1 -1
  48. package/dist/animation-asset-validator.js +80 -1
  49. package/dist/animation-asset-validator.js.map +1 -1
  50. package/dist/asset-core-types.d.ts +99 -4
  51. package/dist/asset-core-types.d.ts.map +1 -1
  52. package/dist/asset-inspection-types.d.ts +8 -0
  53. package/dist/asset-inspection-types.d.ts.map +1 -1
  54. package/dist/asset-manifest.d.ts +1 -0
  55. package/dist/asset-manifest.d.ts.map +1 -1
  56. package/dist/asset-manifest.js +13 -4
  57. package/dist/asset-manifest.js.map +1 -1
  58. package/dist/asset-route-typegen.d.ts +37 -0
  59. package/dist/asset-route-typegen.d.ts.map +1 -0
  60. package/dist/asset-route-typegen.js +179 -0
  61. package/dist/asset-route-typegen.js.map +1 -0
  62. package/dist/cli-help.d.ts +1 -1
  63. package/dist/cli-help.d.ts.map +1 -1
  64. package/dist/cli-help.js +9 -4
  65. package/dist/cli-help.js.map +1 -1
  66. package/dist/cli-options.d.ts +7 -0
  67. package/dist/cli-options.d.ts.map +1 -1
  68. package/dist/cli-options.js +33 -2
  69. package/dist/cli-options.js.map +1 -1
  70. package/dist/cli.d.ts +1 -1
  71. package/dist/cli.d.ts.map +1 -1
  72. package/dist/cli.js +126 -11
  73. package/dist/cli.js.map +1 -1
  74. package/dist/codemods/engine-entry-imports.d.ts +22 -0
  75. package/dist/codemods/engine-entry-imports.d.ts.map +1 -0
  76. package/dist/codemods/engine-entry-imports.js +159 -0
  77. package/dist/codemods/engine-entry-imports.js.map +1 -0
  78. package/dist/codemods/lean-imports.d.ts +40 -0
  79. package/dist/codemods/lean-imports.d.ts.map +1 -0
  80. package/dist/codemods/lean-imports.js +175 -0
  81. package/dist/codemods/lean-imports.js.map +1 -0
  82. package/dist/codemods/renderer-imports.d.ts +36 -0
  83. package/dist/codemods/renderer-imports.d.ts.map +1 -0
  84. package/dist/codemods/renderer-imports.js +364 -0
  85. package/dist/codemods/renderer-imports.js.map +1 -0
  86. package/dist/codemods/renderer-mode.d.ts +38 -0
  87. package/dist/codemods/renderer-mode.d.ts.map +1 -0
  88. package/dist/codemods/renderer-mode.js +130 -0
  89. package/dist/codemods/renderer-mode.js.map +1 -0
  90. package/dist/commands/prd01/index.d.ts +8 -0
  91. package/dist/commands/prd01/index.d.ts.map +1 -0
  92. package/dist/commands/prd01/index.js +39 -0
  93. package/dist/commands/prd01/index.js.map +1 -0
  94. package/dist/commands/prd02/environmentsBake.d.ts +6 -0
  95. package/dist/commands/prd02/environmentsBake.d.ts.map +1 -0
  96. package/dist/commands/prd02/environmentsBake.js +174 -0
  97. package/dist/commands/prd02/environmentsBake.js.map +1 -0
  98. package/dist/commands/prd02/index.d.ts +2 -0
  99. package/dist/commands/prd02/index.d.ts.map +1 -0
  100. package/dist/commands/prd02/index.js +26 -0
  101. package/dist/commands/prd02/index.js.map +1 -0
  102. package/dist/commands/prd02/migrateLighting.d.ts +17 -0
  103. package/dist/commands/prd02/migrateLighting.d.ts.map +1 -0
  104. package/dist/commands/prd02/migrateLighting.js +86 -0
  105. package/dist/commands/prd02/migrateLighting.js.map +1 -0
  106. package/dist/commands/prd02/migrateLightingSweep.d.ts +20 -0
  107. package/dist/commands/prd02/migrateLightingSweep.d.ts.map +1 -0
  108. package/dist/commands/prd02/migrateLightingSweep.js +105 -0
  109. package/dist/commands/prd02/migrateLightingSweep.js.map +1 -0
  110. package/dist/commands/prd03/index.d.ts +7 -0
  111. package/dist/commands/prd03/index.d.ts.map +1 -0
  112. package/dist/commands/prd03/index.js +9 -0
  113. package/dist/commands/prd03/index.js.map +1 -0
  114. package/dist/commands/prd04/index.d.ts +10 -0
  115. package/dist/commands/prd04/index.d.ts.map +1 -0
  116. package/dist/commands/prd04/index.js +10 -0
  117. package/dist/commands/prd04/index.js.map +1 -0
  118. package/dist/commands/prd04/modelTintReport.d.ts +16 -0
  119. package/dist/commands/prd04/modelTintReport.d.ts.map +1 -0
  120. package/dist/commands/prd04/modelTintReport.js +114 -0
  121. package/dist/commands/prd04/modelTintReport.js.map +1 -0
  122. package/dist/commands/prd04/pinEmissiveDefaults.d.ts +3 -0
  123. package/dist/commands/prd04/pinEmissiveDefaults.d.ts.map +1 -0
  124. package/dist/commands/prd04/pinEmissiveDefaults.js +36 -0
  125. package/dist/commands/prd04/pinEmissiveDefaults.js.map +1 -0
  126. package/dist/commands/prd05/admit.d.ts +54 -0
  127. package/dist/commands/prd05/admit.d.ts.map +1 -0
  128. package/dist/commands/prd05/admit.js +153 -0
  129. package/dist/commands/prd05/admit.js.map +1 -0
  130. package/dist/commands/prd05/codemods/assetsRouteModules.d.ts +3 -0
  131. package/dist/commands/prd05/codemods/assetsRouteModules.d.ts.map +1 -0
  132. package/dist/commands/prd05/codemods/assetsRouteModules.js +92 -0
  133. package/dist/commands/prd05/codemods/assetsRouteModules.js.map +1 -0
  134. package/dist/commands/prd05/index.d.ts +9 -0
  135. package/dist/commands/prd05/index.d.ts.map +1 -0
  136. package/dist/commands/prd05/index.js +171 -0
  137. package/dist/commands/prd05/index.js.map +1 -0
  138. package/dist/commands/prd05/library.d.ts +23 -0
  139. package/dist/commands/prd05/library.d.ts.map +1 -0
  140. package/dist/commands/prd05/library.js +245 -0
  141. package/dist/commands/prd05/library.js.map +1 -0
  142. package/dist/commands/prd05/lookdev.d.ts +14 -0
  143. package/dist/commands/prd05/lookdev.d.ts.map +1 -0
  144. package/dist/commands/prd05/lookdev.js +68 -0
  145. package/dist/commands/prd05/lookdev.js.map +1 -0
  146. package/dist/commands/prd05/optimize.d.ts +16 -0
  147. package/dist/commands/prd05/optimize.d.ts.map +1 -0
  148. package/dist/commands/prd05/optimize.js +55 -0
  149. package/dist/commands/prd05/optimize.js.map +1 -0
  150. package/dist/commands/prd05/prune.d.ts +26 -0
  151. package/dist/commands/prd05/prune.d.ts.map +1 -0
  152. package/dist/commands/prd05/prune.js +104 -0
  153. package/dist/commands/prd05/prune.js.map +1 -0
  154. package/dist/commands/prd05/review.d.ts +24 -0
  155. package/dist/commands/prd05/review.d.ts.map +1 -0
  156. package/dist/commands/prd05/review.js +40 -0
  157. package/dist/commands/prd05/review.js.map +1 -0
  158. package/dist/commands/prd06/index.d.ts +6 -0
  159. package/dist/commands/prd06/index.d.ts.map +1 -0
  160. package/dist/commands/prd06/index.js +86 -0
  161. package/dist/commands/prd06/index.js.map +1 -0
  162. package/dist/commands/prd06/inspectAnimationClips.d.ts +86 -0
  163. package/dist/commands/prd06/inspectAnimationClips.d.ts.map +1 -0
  164. package/dist/commands/prd06/inspectAnimationClips.js +168 -0
  165. package/dist/commands/prd06/inspectAnimationClips.js.map +1 -0
  166. package/dist/commands/prd06/validateHero.d.ts +18 -0
  167. package/dist/commands/prd06/validateHero.d.ts.map +1 -0
  168. package/dist/commands/prd06/validateHero.js +91 -0
  169. package/dist/commands/prd06/validateHero.js.map +1 -0
  170. package/dist/commands/prd07/codemods.d.ts +28 -0
  171. package/dist/commands/prd07/codemods.d.ts.map +1 -0
  172. package/dist/commands/prd07/codemods.js +155 -0
  173. package/dist/commands/prd07/codemods.js.map +1 -0
  174. package/dist/commands/prd07/index.d.ts +2 -0
  175. package/dist/commands/prd07/index.d.ts.map +1 -0
  176. package/dist/commands/prd07/index.js +151 -0
  177. package/dist/commands/prd07/index.js.map +1 -0
  178. package/dist/commands/prd08/feelLint.d.ts +13 -0
  179. package/dist/commands/prd08/feelLint.d.ts.map +1 -0
  180. package/dist/commands/prd08/feelLint.js +32 -0
  181. package/dist/commands/prd08/feelLint.js.map +1 -0
  182. package/dist/commands/prd08/index.d.ts +2 -0
  183. package/dist/commands/prd08/index.d.ts.map +1 -0
  184. package/dist/commands/prd08/index.js +16 -0
  185. package/dist/commands/prd08/index.js.map +1 -0
  186. package/dist/commands/prd08/motionReport.d.ts +94 -0
  187. package/dist/commands/prd08/motionReport.d.ts.map +1 -0
  188. package/dist/commands/prd08/motionReport.js +197 -0
  189. package/dist/commands/prd08/motionReport.js.map +1 -0
  190. package/dist/commands/prd09/codemods/audio-wrapper.d.ts +9 -0
  191. package/dist/commands/prd09/codemods/audio-wrapper.d.ts.map +1 -0
  192. package/dist/commands/prd09/codemods/audio-wrapper.js +30 -0
  193. package/dist/commands/prd09/codemods/audio-wrapper.js.map +1 -0
  194. package/dist/commands/prd09/codemods/capture-branches.d.ts +10 -0
  195. package/dist/commands/prd09/codemods/capture-branches.d.ts.map +1 -0
  196. package/dist/commands/prd09/codemods/capture-branches.js +54 -0
  197. package/dist/commands/prd09/codemods/capture-branches.js.map +1 -0
  198. package/dist/commands/prd09/codemods/evidence-globals.d.ts +8 -0
  199. package/dist/commands/prd09/codemods/evidence-globals.d.ts.map +1 -0
  200. package/dist/commands/prd09/codemods/evidence-globals.js +19 -0
  201. package/dist/commands/prd09/codemods/evidence-globals.js.map +1 -0
  202. package/dist/commands/prd09/codemods/perf-script.d.ts +8 -0
  203. package/dist/commands/prd09/codemods/perf-script.d.ts.map +1 -0
  204. package/dist/commands/prd09/codemods/perf-script.js +24 -0
  205. package/dist/commands/prd09/codemods/perf-script.js.map +1 -0
  206. package/dist/commands/prd09/index.d.ts +8 -0
  207. package/dist/commands/prd09/index.d.ts.map +1 -0
  208. package/dist/commands/prd09/index.js +19 -0
  209. package/dist/commands/prd09/index.js.map +1 -0
  210. package/dist/commands/prd09/perf-report.d.ts +56 -0
  211. package/dist/commands/prd09/perf-report.d.ts.map +1 -0
  212. package/dist/commands/prd09/perf-report.js +118 -0
  213. package/dist/commands/prd09/perf-report.js.map +1 -0
  214. package/dist/commands/prd09/sfx-admit.d.ts +18 -0
  215. package/dist/commands/prd09/sfx-admit.d.ts.map +1 -0
  216. package/dist/commands/prd09/sfx-admit.js +120 -0
  217. package/dist/commands/prd09/sfx-admit.js.map +1 -0
  218. package/dist/commands/prd10/index.d.ts +2 -0
  219. package/dist/commands/prd10/index.d.ts.map +1 -0
  220. package/dist/commands/prd10/index.js +109 -0
  221. package/dist/commands/prd10/index.js.map +1 -0
  222. package/dist/commands/prd11/batchOptout.d.ts +35 -0
  223. package/dist/commands/prd11/batchOptout.d.ts.map +1 -0
  224. package/dist/commands/prd11/batchOptout.js +155 -0
  225. package/dist/commands/prd11/batchOptout.js.map +1 -0
  226. package/dist/commands/prd11/index.d.ts +2 -0
  227. package/dist/commands/prd11/index.d.ts.map +1 -0
  228. package/dist/commands/prd11/index.js +13 -0
  229. package/dist/commands/prd11/index.js.map +1 -0
  230. package/dist/commands/prd11/perfGate.d.ts +15 -0
  231. package/dist/commands/prd11/perfGate.d.ts.map +1 -0
  232. package/dist/commands/prd11/perfGate.js +98 -0
  233. package/dist/commands/prd11/perfGate.js.map +1 -0
  234. package/dist/commands/prd13/index.d.ts +15 -0
  235. package/dist/commands/prd13/index.d.ts.map +1 -0
  236. package/dist/commands/prd13/index.js +26 -0
  237. package/dist/commands/prd13/index.js.map +1 -0
  238. package/dist/commands/prd13/run.d.ts +10 -0
  239. package/dist/commands/prd13/run.d.ts.map +1 -0
  240. package/dist/commands/prd13/run.js +29 -0
  241. package/dist/commands/prd13/run.js.map +1 -0
  242. package/dist/commands/prd14/index.d.ts +6 -0
  243. package/dist/commands/prd14/index.d.ts.map +1 -0
  244. package/dist/commands/prd14/index.js +6 -0
  245. package/dist/commands/prd14/index.js.map +1 -0
  246. package/dist/commands/prd15/index.d.ts +8 -0
  247. package/dist/commands/prd15/index.d.ts.map +1 -0
  248. package/dist/commands/prd15/index.js +152 -0
  249. package/dist/commands/prd15/index.js.map +1 -0
  250. package/dist/commands/registry.d.ts +19 -0
  251. package/dist/commands/registry.d.ts.map +1 -0
  252. package/dist/commands/registry.js +19 -0
  253. package/dist/commands/registry.js.map +1 -0
  254. package/dist/contracts/assetManifest.d.ts +80 -0
  255. package/dist/contracts/assetManifest.d.ts.map +1 -0
  256. package/dist/contracts/assetManifest.js +9 -0
  257. package/dist/contracts/assetManifest.js.map +1 -0
  258. package/dist/contracts/commands.d.ts +53 -0
  259. package/dist/contracts/commands.d.ts.map +1 -0
  260. package/dist/contracts/commands.js +37 -0
  261. package/dist/contracts/commands.js.map +1 -0
  262. package/dist/index.d.ts +17 -1
  263. package/dist/index.d.ts.map +1 -1
  264. package/dist/index.js +271 -71
  265. package/dist/index.js.map +1 -1
  266. package/dist/library-manifest.d.ts +86 -0
  267. package/dist/library-manifest.d.ts.map +1 -0
  268. package/dist/library-manifest.js +95 -0
  269. package/dist/library-manifest.js.map +1 -0
  270. package/dist/look/capture.d.ts +51 -0
  271. package/dist/look/capture.d.ts.map +1 -0
  272. package/dist/look/capture.js +229 -0
  273. package/dist/look/capture.js.map +1 -0
  274. package/dist/look/judge.d.ts +24 -0
  275. package/dist/look/judge.d.ts.map +1 -0
  276. package/dist/look/judge.js +151 -0
  277. package/dist/look/judge.js.map +1 -0
  278. package/dist/look/lint-static.d.ts +45 -0
  279. package/dist/look/lint-static.d.ts.map +1 -0
  280. package/dist/look/lint-static.js +241 -0
  281. package/dist/look/lint-static.js.map +1 -0
  282. package/dist/look/rubric.d.ts +70 -0
  283. package/dist/look/rubric.d.ts.map +1 -0
  284. package/dist/look/rubric.js +169 -0
  285. package/dist/look/rubric.js.map +1 -0
  286. package/dist/meshy/import.d.ts +7 -1
  287. package/dist/meshy/import.d.ts.map +1 -1
  288. package/dist/meshy/import.js +80 -6
  289. package/dist/meshy/import.js.map +1 -1
  290. package/dist/migrate-three/CompatibilityWarnings.d.ts +6 -0
  291. package/dist/migrate-three/CompatibilityWarnings.d.ts.map +1 -0
  292. package/dist/migrate-three/CompatibilityWarnings.js +24 -0
  293. package/dist/migrate-three/CompatibilityWarnings.js.map +1 -0
  294. package/dist/migrate-three/ImportMap.d.ts +19 -0
  295. package/dist/migrate-three/ImportMap.d.ts.map +1 -0
  296. package/dist/migrate-three/ImportMap.js +35 -0
  297. package/dist/migrate-three/ImportMap.js.map +1 -0
  298. package/dist/migrate-three/R3fMigration.d.ts +32 -0
  299. package/dist/migrate-three/R3fMigration.d.ts.map +1 -0
  300. package/dist/migrate-three/R3fMigration.js +70 -0
  301. package/dist/migrate-three/R3fMigration.js.map +1 -0
  302. package/dist/migrate-three/ThreeToA3DAdapter.d.ts +8 -0
  303. package/dist/migrate-three/ThreeToA3DAdapter.d.ts.map +1 -0
  304. package/dist/migrate-three/ThreeToA3DAdapter.js +20 -0
  305. package/dist/migrate-three/ThreeToA3DAdapter.js.map +1 -0
  306. package/dist/migrate-three/emit.d.ts +21 -0
  307. package/dist/migrate-three/emit.d.ts.map +1 -0
  308. package/dist/migrate-three/emit.js +117 -0
  309. package/dist/migrate-three/emit.js.map +1 -0
  310. package/dist/migrate-three/mappings.d.ts +21 -0
  311. package/dist/migrate-three/mappings.d.ts.map +1 -0
  312. package/dist/migrate-three/mappings.js +42 -0
  313. package/dist/migrate-three/mappings.js.map +1 -0
  314. package/dist/migrate-three/parse.d.ts +20 -0
  315. package/dist/migrate-three/parse.d.ts.map +1 -0
  316. package/dist/migrate-three/parse.js +56 -0
  317. package/dist/migrate-three/parse.js.map +1 -0
  318. package/dist/migrate-three/report.d.ts +18 -0
  319. package/dist/migrate-three/report.d.ts.map +1 -0
  320. package/dist/migrate-three/report.js +16 -0
  321. package/dist/migrate-three/report.js.map +1 -0
  322. package/dist/pull-bridge/adapters.d.ts +1 -1
  323. package/dist/pull-bridge/adapters.d.ts.map +1 -1
  324. package/dist/pull-bridge/adapters.js +17 -4
  325. package/dist/pull-bridge/adapters.js.map +1 -1
  326. package/dist/pull-bridge/provenance.d.ts.map +1 -1
  327. package/dist/pull-bridge/provenance.js +3 -2
  328. package/dist/pull-bridge/provenance.js.map +1 -1
  329. package/dist/pull-bridge/pullable.d.ts.map +1 -1
  330. package/dist/pull-bridge/pullable.js +14 -3
  331. package/dist/pull-bridge/pullable.js.map +1 -1
  332. package/dist/pull-bridge/scoring.d.ts +36 -8
  333. package/dist/pull-bridge/scoring.d.ts.map +1 -1
  334. package/dist/pull-bridge/scoring.js +143 -47
  335. package/dist/pull-bridge/scoring.js.map +1 -1
  336. package/dist/pull-bridge/search.d.ts +2 -0
  337. package/dist/pull-bridge/search.d.ts.map +1 -1
  338. package/dist/pull-bridge/search.js +17 -10
  339. package/dist/pull-bridge/search.js.map +1 -1
  340. package/dist/pull-bridge.d.ts +2 -2
  341. package/dist/pull-bridge.d.ts.map +1 -1
  342. package/dist/pull-bridge.js +24 -8
  343. package/dist/pull-bridge.js.map +1 -1
  344. package/package.json +6 -3
  345. package/skills/agent-files/AGENTS.md +3 -0
  346. package/skills/aura3d-animation-studio/SKILL.md +153 -0
  347. package/skills/aura3d-animation-studio/references/shot-looks.md +26 -0
  348. package/skills/aura3d-art-direction/SKILL.md +84 -0
  349. package/skills/aura3d-art-direction/references/failure-gallery.md +64 -0
  350. package/skills/aura3d-art-direction/references/framing-and-shots.md +45 -0
  351. package/skills/aura3d-art-direction/references/look-recipes.md +32 -0
  352. package/skills/aura3d-art-direction/references/quality-bar.md +103 -0
  353. package/skills/aura3d-art-direction/references/reference-frames.md +82 -0
  354. package/skills/aura3d-assets/SKILL.md +132 -0
  355. package/skills/aura3d-assets/references/preview-under-look.md +26 -0
  356. package/skills/aura3d-browser-game/SKILL.md +127 -0
  357. package/skills/aura3d-browser-game/references/genre-looks.md +52 -0
  358. package/skills/aura3d-character-animation/SKILL.md +129 -0
  359. package/skills/aura3d-character-animation/references/stage-and-lighting.md +31 -0
  360. package/skills/aura3d-core/SKILL.md +121 -0
  361. package/skills/aura3d-core/references/boundaries.md +91 -0
  362. package/skills/aura3d-evidence-review/SKILL.md +106 -0
  363. package/skills/aura3d-game-art/SKILL.md +118 -0
  364. package/skills/aura3d-game-art/references/sheet-check.mjs +58 -0
  365. package/skills/aura3d-game-art/references/sprite-palettes.md +25 -0
  366. package/skills/aura3d-materials-environments/SKILL.md +139 -0
  367. package/skills/aura3d-performance/SKILL.md +97 -0
  368. package/skills/aura3d-retexture/SKILL.md +115 -0
  369. package/skills/aura3d-retexture/references/geometry-hash.mjs +89 -0
  370. package/skills/aura3d-scene-authoring/SKILL.md +132 -0
  371. package/skills/aura3d-scene-authoring/references/look-by-family.md +28 -0
  372. package/skills/aura3d-threejs-migration/SKILL.md +125 -0
  373. package/skills/aura3d-threejs-migration/references/look-mapping.md +27 -0
  374. package/skills/llms.txt +117 -0
  375. package/skills/manifest.json +163 -0
  376. package/skills/meshy-cli/SKILL.md +133 -0
package/dist/index.js CHANGED
@@ -1,8 +1,16 @@
1
1
  import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
2
+ import { execFileSync } from "node:child_process";
2
3
  import { createHash } from "node:crypto";
3
- import { dirname, extname, join, relative, resolve } from "node:path";
4
+ import { createRequire } from "node:module";
5
+ import { fileURLToPath } from "node:url";
6
+ import { dirname, extname, join, relative, resolve, sep } from "node:path";
4
7
  import { inflateSync } from "node:zlib";
8
+ import { writeAgentSkills } from "create-aura3d";
9
+ import { measureLoudness } from "@aura3d/audio";
5
10
  import { admitAssetForRole } from "./asset-role-admission.js";
11
+ import { hasStylizedFlatApproval } from "./admission/artDirection.js";
12
+ import { AUDIO_SYNTH_RELEASE_ALLOWLIST, isSynthesizedAudioProvenance } from "./admission/audio.js";
13
+ import { profileForRole, requiresPbrTextures } from "./admission/profiles.js";
6
14
  import { DEFAULT_AURA_ASSET_MANIFEST, DEFAULT_AURA_ASSET_OUTPUT_DIR, DEFAULT_AURA_ASSET_PUBLIC_PATH, DEFAULT_AURA_ASSET_TYPEGEN } from "./asset-constants.js";
7
15
  import { shouldScanSource, validateAssetSource } from "./asset-source-validation.js";
8
16
  import { listAssets, readAssetManifest, writeAssetManifest, writeTypedAssets } from "./asset-manifest.js";
@@ -99,6 +107,39 @@ export function readRenderedProbeMetadata(options) {
99
107
  ...(foregroundBounds ? { foregroundBounds } : {})
100
108
  };
101
109
  }
110
+ /**
111
+ * BS.1770 loudness + true-peak for `assets add --type audio` — the same
112
+ * decode→measureLoudness path `sfx admit` uses (48 kHz f32 PCM). Returns
113
+ * `loudnessMeasured: true` even when integrated LUFS is unmeasurable
114
+ * (sub-400 ms files), so a short blip records a measured-null rather than
115
+ * looking unmeasured to the C-25 release gate. `undefined` when ffmpeg is
116
+ * missing or the file will not decode.
117
+ */
118
+ function measureAudioLoudness(sourcePath) {
119
+ try {
120
+ const channelCount = Number(execFileSync("ffprobe", ["-v", "error", "-select_streams", "a:0", "-show_entries", "stream=channels", "-of", "csv=p=0", sourcePath], {
121
+ maxBuffer: 1 << 24
122
+ })
123
+ .toString("utf8")
124
+ .trim()) || 1;
125
+ const pcm = execFileSync("ffmpeg", ["-hide_banner", "-loglevel", "error", "-y", "-i", sourcePath, "-f", "f32le", "-ac", String(channelCount), "-ar", "48000", "-"], { maxBuffer: 1 << 28 });
126
+ const channels = Array.from({ length: channelCount }, (_, c) => {
127
+ const out = new Float32Array(pcm.length / 4 / channelCount);
128
+ for (let i = 0; i < out.length; i++)
129
+ out[i] = pcm.readFloatLE((i * channelCount + c) * 4);
130
+ return out;
131
+ });
132
+ const measured = measureLoudness({ channels, sampleRate: 48_000 });
133
+ return {
134
+ loudnessMeasured: true,
135
+ ...(Number.isFinite(measured.lufs) ? { loudnessLufs: measured.lufs } : {}),
136
+ truePeakDb: measured.truePeakDb
137
+ };
138
+ }
139
+ catch {
140
+ return undefined;
141
+ }
142
+ }
102
143
  export function addAsset(options) {
103
144
  const projectDir = resolve(options.projectDir ?? process.cwd());
104
145
  const sourcePath = resolve(projectDir, options.file);
@@ -170,6 +211,29 @@ export function addAsset(options) {
170
211
  ...(options.suitabilityReason ?? existing?.suitabilityReason ? { suitabilityReason: options.suitabilityReason ?? existing?.suitabilityReason } : {}),
171
212
  ...(options.renderedProbe ?? existing?.renderedProbe ? { renderedProbe: options.renderedProbe ?? existing?.renderedProbe } : {}),
172
213
  ...(options.gameGeometry ?? existing?.gameGeometry ? { gameGeometry: options.gameGeometry ?? existing?.gameGeometry } : {}),
214
+ ...(options.artDirection ?? existing?.artDirection ? { artDirection: options.artDirection ?? existing?.artDirection } : {}),
215
+ /*
216
+ * `#165`/C-25: audio entries carry a measured loudness record — `assets
217
+ * add --type audio` runs BS.1770 itself (ffmpeg decode + measureLoudness),
218
+ * and `--loudness-lufs`/`--true-peak-db` remain manual overrides that win
219
+ * over the measured values.
220
+ */
221
+ ...(type === "audio"
222
+ ? (() => {
223
+ const measured = measureAudioLoudness(sourcePath);
224
+ const supplied = options.audio ?? existing?.audio;
225
+ const merged = { ...measured, ...supplied };
226
+ return Object.keys(merged).length > 0 ? { audio: merged } : {};
227
+ })()
228
+ : options.audio ?? existing?.audio
229
+ ? { audio: options.audio ?? existing?.audio }
230
+ : {}),
231
+ // C-17 clip objects: written only when the inspection produced real
232
+ // durations (the lane-06 inspector hook, Q-05-1); a prior richer record is
233
+ // preserved on re-add.
234
+ ...(c17AnimationClips(inspection.animation) ?? existing?.animationClips
235
+ ? { animationClips: c17AnimationClips(inspection.animation) ?? existing?.animationClips }
236
+ : {}),
173
237
  warnings: createAssetWarnings(sourcePath, inspection)
174
238
  };
175
239
  if (options.orientation) {
@@ -182,7 +246,9 @@ export function addAsset(options) {
182
246
  }
183
247
  }
184
248
  const manifest = sortManifest({
185
- schema: "aura3d.assets/1.0",
249
+ // C-17 stub rule: the stored schema is preserved/1.0 until the writer
250
+ // upgrades under A3D_QR_ASSETS (`writeAssetManifest` decides).
251
+ schema: current.schema ?? "aura3d.assets/1.0",
186
252
  assetBasePath: publicPath,
187
253
  outputDir,
188
254
  typegen,
@@ -691,11 +757,31 @@ export function validateAssets(options = {}) {
691
757
  }
692
758
  if (release)
693
759
  warnings.push(...createDurableReleaseProvenanceWarnings(asset, provenance));
760
+ // R-09-1 (lane 09): synthesized audio may not hold `release` unless the id
761
+ // is on the admission allowlist.
762
+ if (release && asset.type === "audio" && isSynthesizedAudioProvenance(provenance) && !AUDIO_SYNTH_RELEASE_ALLOWLIST.includes(asset.id)) {
763
+ warnings.push(`${asset.id}: release audio asset has synthesized provenance without an admission allowlist entry.`);
764
+ }
765
+ // #165 (C-25 sfx provenance, adopted from lane 09's `sfx admit`): a
766
+ // release audio entry requires license + sourceUrl + author + loudness
767
+ // measurements on its `audio` block.
768
+ if (release && asset.type === "audio") {
769
+ const meta = asset.audio;
770
+ const missingAudio = [
771
+ !hasUsableLicenseEvidence(provenance) ? "license" : undefined,
772
+ !(provenance?.sourceUrl || provenance?.sourcePage || meta?.sourceUrl) ? "sourceUrl" : undefined,
773
+ !(provenance?.author || meta?.author) ? "author" : undefined,
774
+ meta?.loudnessLufs === undefined && meta?.loudnessMeasured !== true ? "loudnessLufs" : undefined,
775
+ meta?.truePeakDb === undefined ? "truePeakDb" : undefined,
776
+ ].filter(Boolean);
777
+ if (missingAudio.length)
778
+ failures.push(`${asset.id}: release audio missing C-25 provenance fields: ${missingAudio.join(", ")}.`);
779
+ }
694
780
  warnings.push(...createDerivedMetadataDriftWarnings(outputPath, asset));
695
781
  if (release)
696
- warnings.push(...createReleaseStructuredQualityWarnings(asset));
782
+ warnings.push(...createReleaseStructuredQualityWarnings(projectDir, asset));
697
783
  if (release)
698
- warnings.push(...createReleaseAssetQualityWarnings(asset));
784
+ warnings.push(...createReleaseAssetQualityWarnings(projectDir, asset));
699
785
  if (release)
700
786
  warnings.push(...createReleaseRenderedProbeWarnings(projectDir, manifest, asset));
701
787
  if (release)
@@ -707,7 +793,7 @@ export function validateAssets(options = {}) {
707
793
  const tempProvenance = createTempProvenanceWarning(asset, provenance);
708
794
  if (tempProvenance)
709
795
  warnings.push(tempProvenance);
710
- const storedWarnings = release ? releaseStoredAssetWarnings(asset) : asset.warnings ?? [];
796
+ const storedWarnings = release ? releaseStoredAssetWarnings(projectDir, asset) : asset.warnings ?? [];
711
797
  warnings.push(...storedWarnings.map((warning) => `${asset.id}: ${warning}`));
712
798
  if (asset.format === "gltf") {
713
799
  for (const dependency of asset.dependencies ?? asset.textures) {
@@ -781,7 +867,9 @@ export function checkDeploy(options = {}) {
781
867
  const distDir = normalizeRelativePath(options.distDir ?? "dist");
782
868
  const failures = [];
783
869
  const warnings = [];
870
+ const referencedServed = new Set();
784
871
  for (const asset of manifest.assets) {
872
+ referencedServed.add(normalizeServedUrl(asset.url));
785
873
  const distPath = resolve(projectDir, distDir, asset.url.replace(/^\//, ""));
786
874
  const publicPath = resolve(projectDir, asset.outputPath);
787
875
  if (!existsSync(distPath) && !existsSync(publicPath)) {
@@ -789,6 +877,41 @@ export function checkDeploy(options = {}) {
789
877
  }
790
878
  if (!/[a-f0-9]{8}\.[^.]+$/i.test(asset.url))
791
879
  warnings.push(`${asset.id}: URL is not fingerprinted: ${asset.url}`);
880
+ // §6.8: copy referenced derived files (url/mobile/collision) into the dist
881
+ // tree so a deploy ships exactly what the manifest points at.
882
+ const derived = asset.derived;
883
+ if (derived) {
884
+ for (const served of [derived.url, derived.mobileUrl, derived.collisionUrl]) {
885
+ if (!served)
886
+ continue;
887
+ referencedServed.add(normalizeServedUrl(served));
888
+ const target = resolve(projectDir, distDir, served.replace(/^\//, ""));
889
+ const derivedOutput = served === derived.url && derived.outputPath
890
+ ? derived.outputPath
891
+ : join(dirname(derived.outputPath ?? join("public", manifest.assetBasePath)), served.split("/").pop() ?? served);
892
+ const source = resolve(projectDir, derivedOutput);
893
+ if (!existsSync(source)) {
894
+ failures.push(`Deploy check missing derived asset for "${asset.id}": expected ${derivedOutput} (url ${served})`);
895
+ continue;
896
+ }
897
+ if (!existsSync(target) || !sameBytes(source, target)) {
898
+ mkdirSync(dirname(target), { recursive: true });
899
+ copyFileSync(source, target);
900
+ }
901
+ }
902
+ }
903
+ }
904
+ // §6.8: schema 1.1 manifests make the deploy subset exact — a file in
905
+ // <dist>/<assetBasePath> that no manifest entry references fails the check.
906
+ if (manifest.schema === "aura3d.assets/1.1") {
907
+ const base = manifest.assetBasePath.replace(/\/$/, "");
908
+ const servedRoot = resolve(projectDir, distDir, base.replace(/^\//, ""));
909
+ for (const file of walkFilesUnder(servedRoot)) {
910
+ const asServed = normalizeServedUrl(`${base}${file.slice(servedRoot.length).split(sep).join("/")}`);
911
+ if (!referencedServed.has(asServed)) {
912
+ failures.push(`Deploy check found unreferenced file in ${distDir}: ${file.slice(projectDir.length + 1)}`);
913
+ }
914
+ }
792
915
  }
793
916
  const validation = validateAssets({
794
917
  projectDir,
@@ -905,20 +1028,27 @@ export function createCharacterAssemblyPlan(options) {
905
1028
  };
906
1029
  }
907
1030
  export function initAgentFiles(options) {
1031
+ return initAgentSetup(options).written;
1032
+ }
1033
+ export function initAgentSetup(options) {
908
1034
  const projectDir = resolve(options.projectDir ?? process.cwd());
909
1035
  const targets = options.agent === "all" ? ["generic", "claude", "cursor", "copilot"] : [options.agent];
910
1036
  const written = [];
1037
+ const mode = options.skills ?? "core";
911
1038
  for (const target of targets) {
912
1039
  if (target === "generic")
913
- written.push(writeAgentFile(projectDir, "AGENTS.md", genericAgentText()));
1040
+ written.push(writeAgentFile(projectDir, "AGENTS.md", genericAgentText("AI coding agent", mode !== "none" ? ".agents/skills" : undefined)));
914
1041
  if (target === "claude")
915
- written.push(writeAgentFile(projectDir, ".claude/CLAUDE.md", genericAgentText("Claude")));
1042
+ written.push(writeAgentFile(projectDir, ".claude/CLAUDE.md", genericAgentText("Claude", mode !== "none" ? ".claude/skills" : undefined)));
916
1043
  if (target === "cursor")
917
- written.push(writeAgentFile(projectDir, ".cursor/rules/aura3d.mdc", genericAgentText("Cursor")));
1044
+ written.push(writeAgentFile(projectDir, ".cursor/rules/aura3d.mdc", genericAgentText("Cursor", mode !== "none" ? ".cursor/skills" : undefined)));
918
1045
  if (target === "copilot")
919
- written.push(writeAgentFile(projectDir, ".github/copilot-instructions.md", genericAgentText("GitHub Copilot")));
1046
+ written.push(writeAgentFile(projectDir, ".github/copilot-instructions.md", genericAgentText("GitHub Copilot", mode !== "none" ? ".github/skills" : undefined)));
920
1047
  }
921
- return written;
1048
+ if (mode === "none")
1049
+ return { written, skills: [], skippedUserModified: [] };
1050
+ const result = writeAgentSkills({ projectDir, agent: options.agent, skills: mode, template: options.template, skillsDir: options.skillsDir });
1051
+ return { written: [...written, ...result.written], skills: result.skills, skippedUserModified: result.skippedUserModified };
922
1052
  }
923
1053
  function validateAssetReadiness(profile, options) {
924
1054
  const projectDir = resolve(options.projectDir ?? process.cwd());
@@ -1758,9 +1888,21 @@ function inspectGlb(buffer, baseDir) {
1758
1888
  if (chunkType !== "JSON")
1759
1889
  throw new Error("Invalid GLB JSON chunk. Suggested fix: re-export the GLB.");
1760
1890
  const json = JSON.parse(buffer.toString("utf8", 20, 20 + chunkLength).trim());
1761
- return inspectGltf(json, baseDir);
1891
+ // Q-05-1 (lane 06): carry the BIN chunk through so the enriched clip
1892
+ // inspector can read sampler input times (duration/frameRate).
1893
+ let offset = 20 + chunkLength;
1894
+ let bin;
1895
+ while (offset + 8 <= buffer.length && offset + 8 <= length) {
1896
+ const chunkLen = buffer.readUInt32LE(offset);
1897
+ if (buffer.readUInt32LE(offset + 4) === 0x004e4942) {
1898
+ bin = buffer.subarray(offset + 8, offset + 8 + chunkLen);
1899
+ break;
1900
+ }
1901
+ offset += 8 + chunkLen;
1902
+ }
1903
+ return inspectGltf(json, baseDir, bin);
1762
1904
  }
1763
- function inspectGltf(json, baseDir) {
1905
+ function inspectGltf(json, baseDir, bin) {
1764
1906
  const dependencies = [
1765
1907
  ...(json.images ?? []).map((image) => image.uri).filter(isExternalUri),
1766
1908
  ...(json.buffers ?? []).map((buffer) => buffer.uri).filter(isExternalUri)
@@ -1778,7 +1920,7 @@ function inspectGltf(json, baseDir) {
1778
1920
  materials: (json.materials ?? []).map((material, index) => material.name ?? `material-${index}`),
1779
1921
  materialMetadata: inspectGltfMaterials(json),
1780
1922
  animations: (json.animations ?? []).map((animation, index) => animation.name ?? `clip-${index}`),
1781
- animation: inspectGltfAnimations(json),
1923
+ animation: inspectGltfAnimations(json, bin),
1782
1924
  humanoid: inspectGltfHumanoid(json),
1783
1925
  skeleton: inspectGltfSkeleton(json),
1784
1926
  morphTargets: inspectGltfMorphTargets(json),
@@ -1797,7 +1939,33 @@ function emptyAnimationInspection() {
1797
1939
  messages: ["No embedded animation clips detected."]
1798
1940
  };
1799
1941
  }
1800
- function inspectGltfAnimations(json) {
1942
+ let lane06ClipInspector;
1943
+ function inspectLane06AnimationClips(json, bin) {
1944
+ if (lane06ClipInspector === undefined) {
1945
+ lane06ClipInspector = null;
1946
+ try {
1947
+ const require = createRequire(import.meta.url);
1948
+ const mod = require("./commands/prd06/inspectAnimationClips.js");
1949
+ if (typeof mod?.inspectAnimationClips === "function") {
1950
+ lane06ClipInspector = mod.inspectAnimationClips;
1951
+ }
1952
+ }
1953
+ catch {
1954
+ lane06ClipInspector = null;
1955
+ }
1956
+ }
1957
+ if (!lane06ClipInspector)
1958
+ return undefined;
1959
+ try {
1960
+ const result = lane06ClipInspector(json, bin);
1961
+ return Array.isArray(result) ? result : undefined;
1962
+ }
1963
+ catch {
1964
+ return undefined;
1965
+ }
1966
+ }
1967
+ function inspectGltfAnimations(json, bin) {
1968
+ const lane06Clips = inspectLane06AnimationClips(json, bin);
1801
1969
  const clips = (json.animations ?? []).map((animation, index) => {
1802
1970
  const channels = animation.channels ?? [];
1803
1971
  const targetPaths = uniqueStrings(channels.map((channel) => channel.target?.path).filter(isString));
@@ -1805,13 +1973,18 @@ function inspectGltfAnimations(json) {
1805
1973
  const nodeIndex = channel.target?.node;
1806
1974
  return typeof nodeIndex === "number" ? json.nodes?.[nodeIndex]?.name ?? `node-${nodeIndex}` : undefined;
1807
1975
  }).filter(isString));
1976
+ const name = animation.name ?? `clip-${index}`;
1977
+ const enriched = lane06Clips?.find((clip) => clip.index === index || clip.name === name);
1808
1978
  return {
1809
1979
  index,
1810
- name: animation.name ?? `clip-${index}`,
1980
+ name,
1811
1981
  channelCount: channels.length,
1812
1982
  samplerCount: animation.samplers?.length ?? 0,
1813
1983
  targetPaths,
1814
- targetNodes
1984
+ targetNodes,
1985
+ ...(typeof enriched?.duration === "number" ? { duration: enriched.duration } : {}),
1986
+ ...(typeof enriched?.hasRootMotionCandidate === "boolean" ? { hasRootMotionCandidate: enriched.hasRootMotionCandidate } : {}),
1987
+ ...(typeof enriched?.frameRate === "number" ? { frameRate: enriched.frameRate } : {})
1815
1988
  };
1816
1989
  });
1817
1990
  return {
@@ -1822,6 +1995,18 @@ function inspectGltfAnimations(json) {
1822
1995
  : [`Detected ${clips.length} embedded animation clip${clips.length === 1 ? "" : "s"}.`]
1823
1996
  };
1824
1997
  }
1998
+ /**
1999
+ * C-17 `animationClips` manifest objects (Q-05-1). Emitted only when every
2000
+ * clip carries a real duration from the lane-06 inspector — the names-only
2001
+ * Phase-0 inspection does not fabricate `duration: 0`.
2002
+ */
2003
+ function c17AnimationClips(inspection) {
2004
+ if (inspection.clipCount === 0)
2005
+ return undefined;
2006
+ if (!inspection.clips.every((clip) => typeof clip.duration === "number" && Number.isFinite(clip.duration)))
2007
+ return undefined;
2008
+ return inspection.clips.map((clip) => ({ name: clip.name, duration: clip.duration ?? 0, channelCount: clip.channelCount }));
2009
+ }
1825
2010
  function inspectGltfHumanoid(json) {
1826
2011
  const skinCount = json.skins?.length ?? 0;
1827
2012
  const jointIndexes = uniqueNumbers((json.skins ?? []).flatMap((skin) => skin.joints ?? []));
@@ -2351,7 +2536,11 @@ function createAssetWarnings(path, inspection) {
2351
2536
  const size = statSync(path).size;
2352
2537
  if (size > 25 * 1024 * 1024)
2353
2538
  warnings.push("asset exceeds 25 MB; consider compression before deployment");
2354
- if (!inspection.bounds)
2539
+ // Bounds are only meaningful on geometry-bearing formats — audio/texture
2540
+ // files can never produce them, so warning (and release-blocking) on them
2541
+ // is noise, matching the format scoping the texture/orientation warnings
2542
+ // below already use.
2543
+ if (!inspection.bounds && ["glb", "gltf"].includes(extname(path).slice(1).toLowerCase()))
2355
2544
  warnings.push("bounds could not be extracted");
2356
2545
  if (inspection.textures.length === 0 && ["glb", "gltf"].includes(extname(path).slice(1).toLowerCase()))
2357
2546
  warnings.push("no texture references detected");
@@ -2643,7 +2832,7 @@ function createDerivedMetadataDriftWarnings(outputPath, asset) {
2643
2832
  }
2644
2833
  return warnings;
2645
2834
  }
2646
- function createReleaseStructuredQualityWarnings(asset) {
2835
+ function createReleaseStructuredQualityWarnings(projectDir, asset) {
2647
2836
  if (asset.type !== "model")
2648
2837
  return [];
2649
2838
  const warnings = [];
@@ -2663,7 +2852,7 @@ function createReleaseStructuredQualityWarnings(asset) {
2663
2852
  }
2664
2853
  return warnings;
2665
2854
  }
2666
- function createReleaseAssetQualityWarnings(asset) {
2855
+ function createReleaseAssetQualityWarnings(projectDir, asset) {
2667
2856
  if (asset.type !== "model")
2668
2857
  return [];
2669
2858
  const warnings = [];
@@ -2688,8 +2877,17 @@ function createReleaseAssetQualityWarnings(asset) {
2688
2877
  if (asset.materialMetadata?.some((material) => !material.visible || !material.readable)) {
2689
2878
  warnings.push(`${asset.id}: release primary model has invisible or unreadable material metadata.`);
2690
2879
  }
2691
- if (["glb", "gltf"].includes(asset.format) && asset.textures.length === 0 && !hasHashBoundFlatColorMaterialEvidence(asset)) {
2692
- warnings.push(`${asset.id}: release primary model has no texture references; use only with explicit material/readability evidence.`);
2880
+ if (["glb", "gltf"].includes(asset.format) && asset.textures.length === 0) {
2881
+ // PRD-05 Phase 0: the hash-bound flat-color evidence waiver is deleted.
2882
+ // The check fails unless the role's profile does not require PBR coverage
2883
+ // (G3 waived-by-role) or `artDirection` resolves to a `stylized-flat`
2884
+ // document with an approved look-dev record (G10).
2885
+ const role = asset.role ?? "unknown";
2886
+ const size = asset.boundsMetadata?.size ?? asset.bounds;
2887
+ const profile = profileForRole(role, size);
2888
+ if (requiresPbrTextures(role, profile) && !hasStylizedFlatApproval(projectDir, asset)) {
2889
+ warnings.push(`${asset.id}: release primary model has no texture references; admit through assets admit (G3) or declare a stylized-flat artDirection with an approved look-dev record.`);
2890
+ }
2693
2891
  }
2694
2892
  return warnings;
2695
2893
  }
@@ -2846,32 +3044,18 @@ function hasValidManifestOrientationOverride(asset) {
2846
3044
  return createManifestOrientationOverrideWarnings(asset).length === 0 &&
2847
3045
  asset.orientation?.source === "manifest-override";
2848
3046
  }
2849
- function releaseStoredAssetWarnings(asset) {
3047
+ function releaseStoredAssetWarnings(projectDir, asset) {
2850
3048
  let warnings = asset.warnings ?? [];
2851
3049
  if (hasValidManifestOrientationOverride(asset)) {
2852
3050
  warnings = warnings.filter((warning) => !/orientation metadata missing; facing direction cannot be validated/i.test(warning));
2853
3051
  }
2854
- if (hasHashBoundFlatColorMaterialEvidence(asset)) {
3052
+ // G10: an approved stylized-flat artDirection + look-dev record sanctions
3053
+ // the absence of textures — the stored no-texture warning stops blocking.
3054
+ if (hasStylizedFlatApproval(projectDir, asset)) {
2855
3055
  warnings = warnings.filter((warning) => !/^no texture references detected$/i.test(warning.trim()));
2856
3056
  }
2857
3057
  return warnings;
2858
3058
  }
2859
- function hasHashBoundFlatColorMaterialEvidence(asset) {
2860
- if (asset.materials.length === 0)
2861
- return false;
2862
- const materialMetadata = asset.materialMetadata ?? [];
2863
- if (materialMetadata.length < asset.materials.length)
2864
- return false;
2865
- if (materialMetadata.some((material) => !nonEmpty(material.name) || material.visible !== true || material.readable !== true ||
2866
- typeof material.opacity !== "number" || material.opacity <= 0))
2867
- return false;
2868
- const probe = asset.renderedProbe;
2869
- return nonEmpty(probe?.url) &&
2870
- nonEmpty(probe?.sha256) &&
2871
- nonEmpty(probe?.assetHash) &&
2872
- probe?.assetHash === asset.hash &&
2873
- ["browser-screenshot", "aura-probe-render"].includes(String(probe?.kind));
2874
- }
2875
3059
  function createRenderedProbeForegroundWarnings(assetId, foregroundBounds, probeMetrics) {
2876
3060
  if (!foregroundBounds)
2877
3061
  return [];
@@ -2900,7 +3084,6 @@ function createRenderedProbeForegroundWarnings(assetId, foregroundBounds, probeM
2900
3084
  return warnings;
2901
3085
  }
2902
3086
  function createRoleAwareReleaseQualityWarnings(projectDir, manifest, asset) {
2903
- void projectDir;
2904
3087
  void manifest;
2905
3088
  if (asset.type !== "model" || asset.quality !== "release")
2906
3089
  return [];
@@ -2909,6 +3092,7 @@ function createRoleAwareReleaseQualityWarnings(projectDir, manifest, asset) {
2909
3092
  const suitabilityReason = asset.suitabilityReason?.trim() ?? "";
2910
3093
  const size = asset.boundsMetadata?.size ?? asset.bounds;
2911
3094
  const dimensions = createRoleAwareDimensions(size);
3095
+ const profile = profileForRole(role, dimensions);
2912
3096
  const hasMaterialEvidence = asset.materials.length > 0 && !(asset.materialMetadata?.every((material) => !material.visible || !material.readable) ?? false);
2913
3097
  const hasTextureEvidence = asset.textures.length > 0 || (asset.hierarchy?.textureCount ?? 0) > 0;
2914
3098
  if (role === "unknown") {
@@ -2941,8 +3125,13 @@ function createRoleAwareReleaseQualityWarnings(projectDir, manifest, asset) {
2941
3125
  if (requiresMaterialEvidence(role) && !hasMaterialEvidence) {
2942
3126
  warnings.push(`${asset.id}: role-aware release ${role} validation requires readable material evidence.`);
2943
3127
  }
2944
- if (requiresTextureEvidence(role, suitabilityReason) && !hasTextureEvidence) {
2945
- warnings.push(`${asset.id}: role-aware release ${role} validation requires texture evidence or explicit stylized-material rationale.`);
3128
+ // PRD-05 Phase 0: `requiresTextureEvidence` (the stylized-suitabilityReason
3129
+ // regex waiver) is deleted — texture requirements now come from the §6.2
3130
+ // role profile, matching G3. An approved stylized-flat artDirection + look-dev
3131
+ // record is the only remaining exemption (G10).
3132
+ const stylizedFlatApproved = hasStylizedFlatApproval(projectDir, asset);
3133
+ if (requiresPbrTextures(role, profile) && !hasTextureEvidence && !stylizedFlatApproved) {
3134
+ warnings.push(`${asset.id}: role-aware release ${role} validation requires texture evidence.`);
2946
3135
  }
2947
3136
  if (requiresForwardOrientation(role) && !hasForwardOrientationEvidence(asset, suitabilityReason)) {
2948
3137
  warnings.push(`${asset.id}: role-aware release ${role} validation requires orientation/forward-axis evidence.`);
@@ -3066,14 +3255,6 @@ function hasRoleAwareSuitabilityReason(role, suitabilityReason) {
3066
3255
  function requiresMaterialEvidence(role) {
3067
3256
  return role !== "debug" && role !== "abstract";
3068
3257
  }
3069
- function requiresTextureEvidence(role, suitabilityReason) {
3070
- if (role === "debug" || role === "abstract")
3071
- return false;
3072
- if (/\b(stylized|stylised|flat[-\s]?color|flat[-\s]?colour|untextured|procedural material|clay render|solid material)\b/i.test(suitabilityReason)) {
3073
- return false;
3074
- }
3075
- return role === "character" || role === "vehicle" || role === "product" || role === "track" || role === "world" || role === "environment" || role === "weapon";
3076
- }
3077
3258
  function requiresForwardOrientation(role) {
3078
3259
  return role === "character" || role === "vehicle" || role === "weapon";
3079
3260
  }
@@ -3324,6 +3505,30 @@ function normalizePublicPath(path) {
3324
3505
  const withStart = path.startsWith("/") || path.startsWith("http") ? path : `/${path}`;
3325
3506
  return withStart.endsWith("/") ? withStart : `${withStart}/`;
3326
3507
  }
3508
+ function normalizeServedUrl(url) {
3509
+ const withSlash = url.startsWith("/") ? url : `/${url}`;
3510
+ return withSlash.replace(/\/+/g, "/");
3511
+ }
3512
+ function sameBytes(a, b) {
3513
+ const as = statSync(a);
3514
+ const bs = statSync(b);
3515
+ return as.size === bs.size && readFileSync(a).equals(readFileSync(b));
3516
+ }
3517
+ function* walkFilesUnder(dir) {
3518
+ if (!existsSync(dir))
3519
+ return;
3520
+ const stack = [dir];
3521
+ while (stack.length > 0) {
3522
+ const current = stack.pop();
3523
+ for (const entry of readdirSync(current, { withFileTypes: true })) {
3524
+ const path = join(current, entry.name);
3525
+ if (entry.isDirectory())
3526
+ stack.push(path);
3527
+ else if (entry.isFile())
3528
+ yield path;
3529
+ }
3530
+ }
3531
+ }
3327
3532
  function normalizeRelativePath(path) {
3328
3533
  return path.replaceAll("\\", "/").replace(/^\.\//, "");
3329
3534
  }
@@ -3339,29 +3544,24 @@ function writeAgentFile(projectDir, path, contents) {
3339
3544
  writeFileSync(output, contents);
3340
3545
  return output;
3341
3546
  }
3342
- function genericAgentText(agent = "AI coding agent") {
3547
+ function genericAgentText(agent = "AI coding agent", skillsPath) {
3548
+ const skillsLine = skillsPath
3549
+ ? `Load the Aura3D skills in ./${skillsPath}/ on demand. Start with aura3d-core; it routes to the task skill (scene authoring, assets, evidence review, games, animation, migration, materials, performance).\n`
3550
+ : "";
3551
+ // Q-05-1 (#242): the body is the canonical agent file shipped in
3552
+ // skills/agent-files/AGENTS.md (PRD-13 T2.15), not a copy — scaffolded
3553
+ // files can never drift from it again. Its own `# ` title line is dropped;
3554
+ // the per-agent prelude keeps the heading + skills path.
3555
+ // Both src/index.ts (tsx) and dist/index.js sit one level below the package
3556
+ // root, whose published `files` include `skills/`.
3557
+ const canonicalPath = resolve(fileURLToPath(import.meta.url), "..", "..", "skills", "agent-files", "AGENTS.md");
3558
+ if (!existsSync(canonicalPath)) {
3559
+ throw new Error(`canonical agent file not found at ${canonicalPath}`);
3560
+ }
3561
+ const canonical = readFileSync(canonicalPath, "utf8").replace(/^#[^\n]*\n+/, "").trimEnd();
3343
3562
  return `# Aura3D Instructions For ${agent}
3344
3563
 
3345
- Read ./llms.txt first, then ./docs/agents/README.md.
3346
-
3347
- Use @aura3d/engine public imports only:
3348
- - createAuraApp
3349
- - scene
3350
- - model
3351
- - camera
3352
- - lights
3353
- - material
3354
- - effects
3355
- - timeline
3356
- - interactions
3357
- - defineAuraAssets
3358
-
3359
- Do not invent asset paths or asset ids. Read ./src/aura-assets.ts after running:
3360
-
3361
- npx @aura3d/cli@latest assets add ./assets/model.glb --name model
3362
-
3363
- Use model(assets.model), not model("model").
3364
- Run npm run build and the template route-health/screenshot tests before claiming the scene is done.
3564
+ ${skillsLine}${canonical}
3365
3565
  `;
3366
3566
  }
3367
3567
  function escapeXml(value) {