@aura3d/cli 3.0.1 → 4.0.2

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 (379) hide show
  1. package/README.md +16 -15
  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 +100 -4
  51. package/dist/asset-core-types.d.ts.map +1 -1
  52. package/dist/asset-inspection-types.d.ts +9 -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 +17 -5
  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 +297 -73
  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/admission.d.ts.map +1 -1
  287. package/dist/meshy/admission.js +32 -7
  288. package/dist/meshy/admission.js.map +1 -1
  289. package/dist/meshy/import.d.ts +7 -1
  290. package/dist/meshy/import.d.ts.map +1 -1
  291. package/dist/meshy/import.js +84 -6
  292. package/dist/meshy/import.js.map +1 -1
  293. package/dist/migrate-three/CompatibilityWarnings.d.ts +6 -0
  294. package/dist/migrate-three/CompatibilityWarnings.d.ts.map +1 -0
  295. package/dist/migrate-three/CompatibilityWarnings.js +24 -0
  296. package/dist/migrate-three/CompatibilityWarnings.js.map +1 -0
  297. package/dist/migrate-three/ImportMap.d.ts +19 -0
  298. package/dist/migrate-three/ImportMap.d.ts.map +1 -0
  299. package/dist/migrate-three/ImportMap.js +35 -0
  300. package/dist/migrate-three/ImportMap.js.map +1 -0
  301. package/dist/migrate-three/R3fMigration.d.ts +32 -0
  302. package/dist/migrate-three/R3fMigration.d.ts.map +1 -0
  303. package/dist/migrate-three/R3fMigration.js +70 -0
  304. package/dist/migrate-three/R3fMigration.js.map +1 -0
  305. package/dist/migrate-three/ThreeToA3DAdapter.d.ts +8 -0
  306. package/dist/migrate-three/ThreeToA3DAdapter.d.ts.map +1 -0
  307. package/dist/migrate-three/ThreeToA3DAdapter.js +20 -0
  308. package/dist/migrate-three/ThreeToA3DAdapter.js.map +1 -0
  309. package/dist/migrate-three/emit.d.ts +21 -0
  310. package/dist/migrate-three/emit.d.ts.map +1 -0
  311. package/dist/migrate-three/emit.js +117 -0
  312. package/dist/migrate-three/emit.js.map +1 -0
  313. package/dist/migrate-three/mappings.d.ts +21 -0
  314. package/dist/migrate-three/mappings.d.ts.map +1 -0
  315. package/dist/migrate-three/mappings.js +42 -0
  316. package/dist/migrate-three/mappings.js.map +1 -0
  317. package/dist/migrate-three/parse.d.ts +20 -0
  318. package/dist/migrate-three/parse.d.ts.map +1 -0
  319. package/dist/migrate-three/parse.js +56 -0
  320. package/dist/migrate-three/parse.js.map +1 -0
  321. package/dist/migrate-three/report.d.ts +18 -0
  322. package/dist/migrate-three/report.d.ts.map +1 -0
  323. package/dist/migrate-three/report.js +16 -0
  324. package/dist/migrate-three/report.js.map +1 -0
  325. package/dist/pull-bridge/adapters.d.ts +1 -1
  326. package/dist/pull-bridge/adapters.d.ts.map +1 -1
  327. package/dist/pull-bridge/adapters.js +17 -4
  328. package/dist/pull-bridge/adapters.js.map +1 -1
  329. package/dist/pull-bridge/provenance.d.ts.map +1 -1
  330. package/dist/pull-bridge/provenance.js +3 -2
  331. package/dist/pull-bridge/provenance.js.map +1 -1
  332. package/dist/pull-bridge/pullable.d.ts.map +1 -1
  333. package/dist/pull-bridge/pullable.js +14 -3
  334. package/dist/pull-bridge/pullable.js.map +1 -1
  335. package/dist/pull-bridge/scoring.d.ts +36 -8
  336. package/dist/pull-bridge/scoring.d.ts.map +1 -1
  337. package/dist/pull-bridge/scoring.js +143 -47
  338. package/dist/pull-bridge/scoring.js.map +1 -1
  339. package/dist/pull-bridge/search.d.ts +2 -0
  340. package/dist/pull-bridge/search.d.ts.map +1 -1
  341. package/dist/pull-bridge/search.js +17 -10
  342. package/dist/pull-bridge/search.js.map +1 -1
  343. package/dist/pull-bridge.d.ts +2 -2
  344. package/dist/pull-bridge.d.ts.map +1 -1
  345. package/dist/pull-bridge.js +24 -8
  346. package/dist/pull-bridge.js.map +1 -1
  347. package/package.json +6 -3
  348. package/skills/agent-files/AGENTS.md +3 -0
  349. package/skills/aura3d-animation-studio/SKILL.md +153 -0
  350. package/skills/aura3d-animation-studio/references/shot-looks.md +26 -0
  351. package/skills/aura3d-art-direction/SKILL.md +84 -0
  352. package/skills/aura3d-art-direction/references/failure-gallery.md +64 -0
  353. package/skills/aura3d-art-direction/references/framing-and-shots.md +45 -0
  354. package/skills/aura3d-art-direction/references/look-recipes.md +32 -0
  355. package/skills/aura3d-art-direction/references/quality-bar.md +103 -0
  356. package/skills/aura3d-art-direction/references/reference-frames.md +82 -0
  357. package/skills/aura3d-assets/SKILL.md +151 -0
  358. package/skills/aura3d-assets/references/preview-under-look.md +26 -0
  359. package/skills/aura3d-browser-game/SKILL.md +149 -0
  360. package/skills/aura3d-browser-game/references/genre-looks.md +52 -0
  361. package/skills/aura3d-character-animation/SKILL.md +129 -0
  362. package/skills/aura3d-character-animation/references/stage-and-lighting.md +31 -0
  363. package/skills/aura3d-core/SKILL.md +143 -0
  364. package/skills/aura3d-core/references/boundaries.md +91 -0
  365. package/skills/aura3d-evidence-review/SKILL.md +106 -0
  366. package/skills/aura3d-game-art/SKILL.md +118 -0
  367. package/skills/aura3d-game-art/references/sheet-check.mjs +58 -0
  368. package/skills/aura3d-game-art/references/sprite-palettes.md +25 -0
  369. package/skills/aura3d-materials-environments/SKILL.md +139 -0
  370. package/skills/aura3d-performance/SKILL.md +97 -0
  371. package/skills/aura3d-retexture/SKILL.md +115 -0
  372. package/skills/aura3d-retexture/references/geometry-hash.mjs +89 -0
  373. package/skills/aura3d-scene-authoring/SKILL.md +132 -0
  374. package/skills/aura3d-scene-authoring/references/look-by-family.md +28 -0
  375. package/skills/aura3d-threejs-migration/SKILL.md +125 -0
  376. package/skills/aura3d-threejs-migration/references/look-mapping.md +27 -0
  377. package/skills/llms.txt +147 -0
  378. package/skills/manifest.json +163 -0
  379. package/skills/meshy-cli/SKILL.md +148 -0
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+ // Flipbook sprite-sheet pre-flight for Aura3D `effects.flipbook`.
3
+ // Reads a PNG header (no dependencies) and checks that the sheet divides evenly
4
+ // into columns x rows, that the declared frame count fits the grid, and that the
5
+ // PNG carries an alpha channel. It does not look at pixels; a transparent
6
+ // background and clean frame edges still need a visual check.
7
+ //
8
+ // Usage: node sheet-check.mjs sheet.png --columns 8 --rows 4 [--frames 30]
9
+ import { readFileSync } from "node:fs";
10
+
11
+ const args = process.argv.slice(2);
12
+ const file = args[0];
13
+ const opt = (name) => {
14
+ const i = args.indexOf(`--${name}`);
15
+ return i >= 0 ? Number(args[i + 1]) : undefined;
16
+ };
17
+ const columns = opt("columns");
18
+ const rows = opt("rows");
19
+ if (!file || !columns || !rows) {
20
+ console.error("usage: node sheet-check.mjs sheet.png --columns N --rows N [--frames N]");
21
+ process.exit(2);
22
+ }
23
+ const frames = opt("frames") ?? columns * rows;
24
+
25
+ const buf = readFileSync(file);
26
+ const PNG_SIGNATURE = "89504e470d0a1a0a";
27
+ const failures = [];
28
+ if (buf.subarray(0, 8).toString("hex") !== PNG_SIGNATURE || buf.toString("ascii", 12, 16) !== "IHDR") {
29
+ console.log(JSON.stringify({ ok: false, file, failures: ["not a PNG (flipbook sheets must be PNG with alpha)"] }, null, 2));
30
+ process.exit(1);
31
+ }
32
+ const width = buf.readUInt32BE(16);
33
+ const height = buf.readUInt32BE(20);
34
+ const colorType = buf[25];
35
+ // PNG color types 4 (gray+alpha) and 6 (RGBA) carry alpha; a tRNS chunk adds it to palette images.
36
+ const hasAlpha = colorType === 4 || colorType === 6 || buf.includes(Buffer.from("tRNS"));
37
+
38
+ for (const [name, value] of [["columns", columns], ["rows", rows], ["frames", frames]]) {
39
+ if (!Number.isInteger(value) || value <= 0) failures.push(`${name} must be a positive integer`);
40
+ }
41
+ if (width % columns !== 0) failures.push(`width ${width} is not divisible by ${columns} columns`);
42
+ if (height % rows !== 0) failures.push(`height ${height} is not divisible by ${rows} rows`);
43
+ if (frames > columns * rows) failures.push(`frames ${frames} exceed sheet capacity ${columns * rows}`);
44
+ if (!hasAlpha) failures.push("PNG has no alpha channel; the background cannot be transparent");
45
+
46
+ const cell = [width / columns, height / rows];
47
+ console.log(JSON.stringify({
48
+ ok: failures.length === 0,
49
+ file,
50
+ size: [width, height],
51
+ grid: [columns, rows],
52
+ cell,
53
+ frames,
54
+ emptyCells: columns * rows - frames,
55
+ hasAlpha,
56
+ failures
57
+ }, null, 2));
58
+ process.exitCode = failures.length === 0 ? 0 : 1;
@@ -0,0 +1,25 @@
1
+ # Sprite and flipbook palettes per genre
2
+
3
+ Hue and luminance targets so hand-drawn or generated sprites land inside the
4
+ route's look instead of reading as pasted stickers.
5
+
6
+ | Genre look | Sprite family | Hues (sRGB) | Emissive target |
7
+ | --- | --- | --- | --- |
8
+ | `outdoor-day` | pickups, coins, springs | gold #FFC53D, leaf green #5DBB63, sky blue #56B4F0 | 3× ground luminance |
9
+ | `golden-hour` | brake glow, exhaust, UI accents | amber #FF9E3D, burnt orange #D96C2C, charcoal #2B2623 | 4× asphalt |
10
+ | `arena-fight` | hit sparks, meter fills, KO flash | impact orange #FF7A2B, meter cyan #46E8FF, KO white #FFFFFF | 5× arena floor |
11
+ | `neon-arcade` | pieces, line-clear flash, grid glow | cyan #2EE6FF, magenta #FF3DE8, lime #B8FF2E, violet #8A5BFF | 4× board |
12
+ | `night-city` | signs, window glow, puddle decals | sodium #FFB84D, neon red #FF2E6E, cool cyan #4DD8FF | 3× wet street |
13
+ | `space` | lasers, shields, engine trails | laser magenta #FF4DFF, shield teal #3DFFE8, trail white | 6× starfield |
14
+ | `underwater` | bubbles, biolume, fauna glints | deep teal #1FA8A0, biolume #7DFFD4, coral #FF8A6B | 3× water |
15
+ | `product-studio` | callouts, tag glyphs, swatches | brand accent + neutral greys | none — flat read |
16
+
17
+ ## Drawing rules
18
+
19
+ - Desaturate sprite fills slightly vs. the accent — the grade re-saturates and
20
+ pure-primary fills clip to flat color.
21
+ - Keep alpha edges dark-tolerant: a white halo invisible in the texture viewer
22
+ blooms against `night-city` fog.
23
+ - Flipbook frames must carry their own lighting direction matching the look's
24
+ key (a spark sheet lit from below fights a `golden-hour` key).
25
+ - UI glyphs in DOM HUD use the look's foreground color, not the world palette.
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: aura3d-materials-environments
3
+ description: Chooses and verifies surface looks and lighting environments: built-in `material.*`, `environments.*`, `sky.dayNight`, `weather`, and `water` first, then licensed local textures or HDRIs admitted with `assets add --type texture`, with seam, PBR-channel, and visual-QA checks. Use when a route needs a material, texture set, PBR maps, HDRI or IBL, skybox, night or daytime sky, rain, snow, water, KTX2 textures, or `@aura3d/materials` / `@aura3d/environments` validation.
4
+ ---
5
+
6
+ # Aura3D materials and environments
7
+
8
+ Order is fixed: looks/biomes/env presets first, then built-ins, then a
9
+ licensed local file, then a generated plate as a candidate. There is no
10
+ catalog search for textures or HDRIs today (the asset index has no texture or
11
+ HDRI adapter), so `assets search` will not find them. Shared rules (claim
12
+ labels, typed assets, catalog-first for models, benchmark mode) are in
13
+ [../aura3d-core/references/boundaries.md](../aura3d-core/references/boundaries.md).
14
+
15
+ ## Look target
16
+
17
+ Most scenes need no per-file HDRI at all: `looks.preset(<genre>)` already
18
+ supplies environment light, sky/background, fog and grade — pick it from the
19
+ recipe row in `../aura3d-art-direction/references/look-recipes.md` and only
20
+ descend into manual environments when the look cannot express the mood.
21
+
22
+ ## Establish the contract
23
+
24
+ 1. Run `npx @aura3d/cli@latest --help` and read the `assets add` line and its
25
+ `--type texture|environment` option.
26
+ 2. Read `src/aura-assets.ts` and `aura.assets.json`. Map slots take typed
27
+ `assets.<key>` refs only, never a URL string.
28
+ 3. Check the installed `@aura3d/engine`, `@aura3d/materials`, and
29
+ `@aura3d/environments` versions. The validators below come from the
30
+ `/node` subpaths (`@aura3d/materials/node`, `@aura3d/environments/node`)
31
+ and run in Node scripts, not in browser routes.
32
+ 4. Benchmark mode: `npm install && npm run build`, then stop.
33
+
34
+ ## Procedure
35
+
36
+ Step 1, presets (always try first):
37
+
38
+ 0. Looks and biomes: `looks.preset("outdoor-day" | "night-city" | "product-studio" ...)`
39
+ and `world.biome(<id>)` supply IBL + background + fog + key as one unit;
40
+ `environments.<named>`/`environments.hdri` cover the remaining cases before
41
+ any file admission.
42
+ 1. Materials: `material.pbr(...)`, `material.physical(...)`, `material.metal`,
43
+ `material.glass`, `material.rubber`, `material.fabric`,
44
+ `material.brushedMetal`, `material.ceramic`, `material.matteClay`,
45
+ `material.clearcoatPaint`, and `material.emissive`, plus
46
+ `material.proceduralTextures` (fabric, rubber, brushedMetal, plastic) for
47
+ maps without files. `material.presets()` lists the named specs.
48
+ 2. Environments: `environments.studio`, `environments.materialLab`,
49
+ `environments.productHero`, `environments.nightCinematic`,
50
+ `environments.metalStudio`, `environments.glassStudio`, or
51
+ `environments.forMaterial("metal" | "glass" | "product" | "studio")`.
52
+ 3. Outdoor: `sky.dayNight({ hour })` returns `nodes`, `background`, and
53
+ `dayFactor`; `weather.precipitation({ type: "rain" | "snow" })` and
54
+ `weather.wetGround(...)`; `water.surface({ preset: "calm" | "moderate" |
55
+ "rough" | "storm" })`. Add their `nodes` with `scene().addMany(...)` and use
56
+ the returned `background`.
57
+ 4. Library references for choosing values: `GAME_READY_MATERIAL_PRESETS` (car
58
+ paint, thin glass, brushed metal, skin approximation, and more),
59
+ `listThreeCompatPbrMaterials()`, and `THREE_COMPAT_TEXTURE_SETS`. Check a
60
+ preset in Node with `validateGameReadyMaterialPreset(preset)` or the whole
61
+ library with `validateGameReadyMaterialLibrary()`.
62
+
63
+ Step 2, a licensed local file (Poly Haven or another CC0 / CC-BY source you
64
+ downloaded yourself):
65
+
66
+ 5. Admit each map and each HDRI as a texture:
67
+
68
+ ```sh
69
+ npx @aura3d/cli@latest assets add ./textures/oak_diff_2k.jpg --name oakBase --type texture --license CC0-1.0 --source-page <page> --author "<author>"
70
+ npx @aura3d/cli@latest assets add ./hdri/night_1k.hdr --name nightSky --type texture --license CC0-1.0 --source-page <page> --author "<author>"
71
+ npx @aura3d/cli@latest assets typegen
72
+ ```
73
+
74
+ Use `--type texture` for HDRIs too: `environments.hdri({ texture })` only
75
+ accepts a texture-typed ref, and an `--type environment` ref fails to
76
+ type-check there. Use Radiance `.hdr`, not `.exr`, for IBL.
77
+ 6. Wire maps into one material: `texture` (base color), `normal`,
78
+ `roughnessMap`, `metalnessMap`, `occlusionMap`, `emissiveMap`, with
79
+ `texTransforms` for tiling. Wire the sky with
80
+ `environments.hdri({ texture: assets.nightSky, intensity, rotation })` and an
81
+ optional sharper `reflectionTexture`.
82
+ 7. Reject a PBR set that is missing roughness or metalness data where the
83
+ role expects PBR (metal, painted, or product surfaces). Do not invent the
84
+ missing map with a flat color and call it PBR.
85
+
86
+ Step 3, a generated plate (optional, from an image skill outside Aura3D): keep
87
+ it under `artifacts/`, admit it with `--quality candidate`, and label the
88
+ route `prototype` until the checks below pass.
89
+
90
+ Checks (all steps):
91
+
92
+ 8. HDRI file: in Node, `inspectProductionHDR(path, [width, height])` must
93
+ report a Radiance header and a 2:1 `declaredResolution`. For a manifest
94
+ preset, `verifyThreeCompatHdriFile(preset)` checks the file hash and
95
+ `createThreeCompatEnvironmentDiagnostics(preset)` reports memory and PMREM
96
+ warnings.
97
+ 9. Equirect seam: capture the sky at a yaw that puts the left and right edge
98
+ in frame and confirm no visible seam. `environments.hdri` renders a
99
+ procedural studio fallback first and swaps in the HDRI after load, so
100
+ judge only frames where diagnostics report `iblPixelBacked` true.
101
+ 10. Tiling: capture a surface at a texture scale that repeats the map at least
102
+ 3 times and confirm no visible seam or mirrored repeat.
103
+ 11. On material showcase scenes, `structuralQA.material(nodes)` reports
104
+ `ok` plus per-class structural-name checks (nodes named like
105
+ chrome/glass/rubber actually present). These are diagnostics only —
106
+ acceptance comes from the captured frames.
107
+ 12. KTX2: `.ktx2` files are accepted by `assets add --type texture`, and
108
+ renderer coverage exists only for selected tested cases. Keep a
109
+ PNG/JPG fallback, and make no compression or memory claim without a
110
+ route-level capture.
111
+ 13. Screenshots (normal mode only) run through `npm run test` on CI or a remote
112
+ worker. Hand the claim label to `aura3d-evidence-review`.
113
+
114
+ ## Look-dev loop
115
+
116
+ `aura3d look capture` → judge against the quality-bar rubric → `aura3d look
117
+ lint`. Judge only frames where the HDRI actually loaded (`iblPixelBacked`
118
+ true); a seam visible in one capture re-checks at a different yaw. One change
119
+ per round.
120
+
121
+ ## Stop and report
122
+
123
+ - No built-in matches and no licensed file is available: stop, label the look
124
+ `prototype`, and say a texture or HDRI source is needed. Do not fetch a URL
125
+ you have not verified, and do not claim a catalog texture exists.
126
+ - License or source page is unknown: do not admit the file.
127
+ - The HDRI is not 2:1, has a seam, or never reaches `iblPixelBacked`: report
128
+ it and keep the built-in environment.
129
+ - A PBR role is missing roughness or metalness: reject the set.
130
+ - Any check above was not run: the route is `prototype`, not release.
131
+
132
+ ## References
133
+
134
+ - [Environment lighting](https://github.com/auraoneai/aura3d/blob/main/docs/rendering/environment-lighting.md)
135
+ - [HDR, IBL, tone mapping, and color](https://github.com/auraoneai/aura3d/blob/main/docs/rendering/lighting-environment-color.md)
136
+ - [Texture compression (KTX2/Basis)](https://github.com/auraoneai/aura3d/blob/main/docs/rendering/texture-compression.md)
137
+ - [Material validation source](https://github.com/auraoneai/aura3d/blob/main/packages/engine/src/devtools/materials/MaterialValidation.ts)
138
+ - [HDRI environment source](https://github.com/auraoneai/aura3d/blob/main/packages/engine/src/devtools/environments/HDRIEnvironment.ts)
139
+ - [Sky, weather, and water browser harness](https://github.com/auraoneai/aura3d/blob/main/tests/browser/d3-atmosphere-water-harness.ts)
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: aura3d-performance
3
+ description: Measures and reduces Aura3D frame cost, draw calls, and bundle size with diagnostics, scene-kit budgets, instancing, distance LOD, frustum culling, and KTX2 textures, without turning counters into visual claims. Use when a route is slow, draw calls or bundle size exceed budget, or the task mentions `diagnostics: { overlay: true }`, `sceneKitPerformanceBudget`, `instances.*`, `distanceLod`, `text3D`, KTX2 texture compression, BUNDLE_SIZES, `doctor`, or `check-deploy`.
4
+ ---
5
+
6
+ # Aura3D performance
7
+
8
+ Measure first, change one thing, measure again. Diagnostics counters are
9
+ evidence for performance claims only; they never prove a scene looks right.
10
+ Shared rules (claim labels, forbidden patterns, typed assets, benchmark mode)
11
+ are in [boundaries](../aura3d-core/references/boundaries.md).
12
+
13
+ ## Look target
14
+
15
+ Measure with the final look active: the look sets the DPR cap, the post grade
16
+ (bloom, AO, vignette) and shadow map size — most of the frame cost you are
17
+ optimizing. `looks.appOptions(<id>)` already applies `quality: "auto"`; a
18
+ manual quality override invalidates every measurement that follows.
19
+
20
+ ## Establish the contract
21
+
22
+ 1. Run `npx @aura3d/cli@latest --help` and `npx @aura3d/cli@latest doctor`.
23
+ Fix doctor failures before profiling; warnings are listed separately.
24
+ 2. Read `src/aura-assets.ts` and `aura.assets.json`. Note each asset's
25
+ `sizeBytes`, texture list, and bounds; heavy GLBs and uncompressed textures
26
+ are usually the first cost.
27
+ 3. Check which entry the app imports. New product and game apps should use
28
+ `@aura3d/lean`, `@aura3d/lean/product`, or `@aura3d/lean/game`. The
29
+ `@aura3d/engine` root is a compatibility entry and is far over the new-app
30
+ gzip budget.
31
+ 4. Decide the mode. Benchmark mode: `npm install && npm run build`, then stop.
32
+ No profiling, dev server, or browser capture from the agent.
33
+
34
+ ## Procedure
35
+
36
+ 1. Turn diagnostics on while measuring and off for release screenshots:
37
+
38
+ ```ts
39
+ createAuraApp("#app", { scene, diagnostics: { overlay: true, performancePanel: true } });
40
+ ```
41
+
42
+ The app's diagnostics report `backend`, `fps`, `drawCalls`, `renderSize`,
43
+ asset load states, `warnings`, and `errors`. Record them with the viewport,
44
+ device, and route so the finding reproduces.
45
+ 2. Compare against the budget for the kit you started from:
46
+
47
+ ```ts
48
+ import { sceneKitPerformanceBudget, sceneKits } from "@aura3d/engine";
49
+
50
+ console.log(sceneKitPerformanceBudget("miniGolf"));
51
+ console.log(sceneKits.miniGolf().diagnostics);
52
+ ```
53
+
54
+ Budgets carry `maxDrawCalls`, `estimatedDrawCalls`, `maxGzipBytes`, and
55
+ `targetP50Fps`. FPS targets require calibration on the measuring machine.
56
+ 3. Many repeated objects: replace per-node primitives with one `instances.box`
57
+ (or `instances.sphere`, `instances.plane`, `instances.cylinder`,
58
+ `instances.capsule`, `instances.torus`) node with a transform list. Advanced
59
+ PBR extensions can fall back to expanded draws, so confirm native instanced
60
+ submissions in diagnostics before claiming one draw.
61
+ 4. Distant detail: use `distanceLod` with increasing `maxDistance` levels and a
62
+ `hysteresis` band so the camera cannot flap between levels.
63
+ 5. Large scenes: rely on CPU frustum culling plus the static-bounds BVH. Give
64
+ custom geometry explicit bounds via `geometry.custom`. There is no GPU
65
+ occlusion culling; do not claim it.
66
+ 6. Text: `text3D` is extruded mesh text (A-Z, 0-9, space, dash, period);
67
+ `labels.billboard` is DOM UI. Pick by need, not to save draws.
68
+ 7. Particles: check `particles.diagnostics` for total particles and
69
+ estimated update cost before raising counts.
70
+ 8. Textures: prefer KTX2/Basis-compressed textures supplied through typed
71
+ assets. Compression support is bounded to the tested decoder paths; verify
72
+ in the browser before claiming a memory or load-time win.
73
+ 9. Bundle: keep new imports on the lean entry and avoid pulling devtools or
74
+ cinematic helpers into the critical path. In the Aura3D monorepo,
75
+ `pnpm check:bundle-size` regenerates BUNDLE_SIZES; never raise a budget to
76
+ manufacture a pass.
77
+ 10. Ship check: `npm run build`, then
78
+ `npx @aura3d/cli@latest check-deploy --dist dist`. Browser frame-time and
79
+ screenshot runs (`npm run test`, Playwright) go to CI or a remote runner.
80
+
81
+ ## Stop and report
82
+
83
+ - `doctor` or `check-deploy` fails: stop and fix that first; label `blocked`.
84
+ - A win is measured on one machine only: call it directional, name the
85
+ machine and workload, and do not generalize it to a frame-time guarantee.
86
+ - A performance change alters the rendered scene: rerun screenshot review
87
+ through `aura3d-evidence-review` before shipping.
88
+ - GPU timing is unavailable or noisy on the device: say so; do not fill in.
89
+
90
+ ## References
91
+
92
+ - [Shared boundaries](../aura3d-core/references/boundaries.md)
93
+ - [Profiling and diagnostics](https://github.com/auraoneai/aura3d/blob/main/docs/debug/profiling-and-diagnostics.md)
94
+ - [Bundle sizes](https://github.com/auraoneai/aura3d/blob/main/BUNDLE_SIZES.md)
95
+ - [Texture compression](https://github.com/auraoneai/aura3d/blob/main/docs/rendering/texture-compression.md)
96
+ - [Geometry, instancing, LOD, text](https://github.com/auraoneai/aura3d/blob/main/docs/rendering/geometry-instancing-lod-text.md)
97
+ - [Deployment](https://aura3d.auraone.ai/docs/deployment.html)
@@ -0,0 +1,115 @@
1
+ ---
2
+ name: aura3d-retexture
3
+ description: Restyles a finished, admitted mesh while proving the geometry is untouched: before and after `assets inspect` bounds plus a position-accessor hash diff, one material family per map set, and a matched before and after screenshot filmstrip. Use when retexturing, recoloring, reskinning, or restyling an existing GLB or typed `assets.<key>` model, including after `meshy retexture`, a DCC texture pass, or a `model(asset, { material })` tint.
4
+ ---
5
+
6
+ # Aura3D retexture (geometry untouched)
7
+
8
+ A retexture changes how a mesh looks, never its shape. The proof is numeric
9
+ (identical bounds and position data) plus visual (a matched before and after
10
+ filmstrip). Orbit or turnaround views are not produced: the engine renders any
11
+ angle of the real mesh through `camera.*`, and painted angles would be
12
+ unverifiable. Shared rules (claim labels, typed assets, paid generation,
13
+ benchmark mode) are in
14
+ [../aura3d-core/references/boundaries.md](../aura3d-core/references/boundaries.md).
15
+
16
+ ## Look target
17
+
18
+ Judge a retexture under the look it will ship in — the same map set reads warm
19
+ under `golden-hour` and cold under `night-city`. Fix the route's look preset
20
+ first, then iterate on maps; a recolor tuned against flat lighting drifts
21
+ again under the real grade.
22
+
23
+ ## Establish the contract
24
+
25
+ 1. Run `npx @aura3d/cli@latest --help` and read the `assets inspect` and
26
+ `assets add` lines.
27
+ 2. Read `aura.assets.json` and `src/aura-assets.ts`. The source mesh must be
28
+ an admitted typed asset with a license. Keep its original file; never
29
+ overwrite it in place.
30
+ 3. Choose the path:
31
+ - Offline: a new GLB with new maps (a `meshy retexture` result through the
32
+ `meshy-cli` skill, or a DCC texture pass). This is the only way to change
33
+ texture maps.
34
+ - Runtime tint: `model(assets.x, { material: material.pbr({ color, roughness, metallic }) })`.
35
+ On typed GLBs this applies a flat tint that replaces surface textures on
36
+ the whole model. It cannot target one part or add maps.
37
+ 4. Benchmark mode: `npm install && npm run build`, then stop.
38
+
39
+ ## Procedure
40
+
41
+ 1. Record the before state:
42
+
43
+ ```sh
44
+ npx @aura3d/cli@latest assets inspect ./assets/source.glb --license > artifacts/retexture/before.inspect.json
45
+ node .agents/skills/aura3d-retexture/references/geometry-hash.mjs ./assets/source.glb > artifacts/retexture/before.geometry.json
46
+ ```
47
+
48
+ (Adjust the script path to wherever your agent client installed this
49
+ skill.) Keep `bounds`, `boundsMetadata`, `materials`, and `nodeNames` from
50
+ the inspection, and `geometryHash` plus per-primitive hashes from the
51
+ script. `assets inspect` reports bounds but no vertex hash, and the
52
+ manifest `hash` covers the whole file (textures included), so it always
53
+ changes on a retexture and proves nothing about geometry.
54
+ 2. Plan one material family per map set. List each glTF material by name
55
+ (from `materials`), assign it one target family (for example painted
56
+ metal, worn leather, matte plastic), and give each family exactly one map
57
+ set (base color, normal, roughness and metalness, occlusion). Never share
58
+ one map set across two families, and never split one family across two
59
+ map sets.
60
+ 3. Produce the after file as a new GLB in `artifacts/retexture/`. Only
61
+ materials, images, and textures may change. The node tree, mesh
62
+ primitives, UVs, skin, and morph targets stay as they are.
63
+ 4. Prove the geometry is untouched:
64
+
65
+ ```sh
66
+ node .agents/skills/aura3d-retexture/references/geometry-hash.mjs ./assets/source.glb artifacts/retexture/after.glb
67
+ npx @aura3d/cli@latest assets inspect artifacts/retexture/after.glb --license > artifacts/retexture/after.inspect.json
68
+ ```
69
+
70
+ The script exits 0 only when `geometryUntouched` is true (the same
71
+ POSITION and index bytes for every primitive). The inspections must show
72
+ identical `boundsMetadata.min`, `boundsMetadata.max`, and `nodeNames`, and
73
+ the same material names unless you renamed them on purpose. Draco
74
+ geometry must be decoded before hashing. For a runtime tint the file is
75
+ unchanged, so record that and skip the hash.
76
+ 5. Admit the after file as its own asset with provenance, leaving the
77
+ original entry in place:
78
+
79
+ ```sh
80
+ npx @aura3d/cli@latest assets add artifacts/retexture/after.glb --name sourceRestyled --license CC-BY-4.0 --author "<author>" --quality candidate --role product
81
+ npx @aura3d/cli@latest assets typegen
82
+ ```
83
+
84
+ Carry the source license forward; a derived file inherits its terms.
85
+ 6. Capture the filmstrip (normal mode, via `npm run test` on CI or a remote
86
+ worker): the same camera, lights, environment, exposure, and viewport for
87
+ before and after, 3 to 5 fixed views, for example
88
+ `camera.frameAsset(assets.source)` plus fixed `camera.perspective(...)`
89
+ positions. Only the asset key may differ between the paired frames. Place
90
+ each before frame beside its after frame.
91
+ 7. Report: the family-to-map-set table, both geometry reports, the bounds
92
+ comparison, the filmstrip, and the new asset key. Hand the label to
93
+ `aura3d-evidence-review`; a retextured asset stays `candidate` until
94
+ reviewed.
95
+
96
+ ## Stop and report
97
+
98
+ - `geometryUntouched` is false, or bounds or node names differ: stop. The
99
+ file is a remesh or rebuild, not a retexture. Report the changed
100
+ primitives, and do not admit it as a restyle of the source.
101
+ - The request needs per-part maps, but only the runtime tint path is
102
+ available: report the gap; the tint recolors the whole model.
103
+ - The source has no license or provenance, or its terms forbid derivatives:
104
+ do not retexture it.
105
+ - A mismatched camera, lighting, or viewport between before and after frames
106
+ makes the filmstrip invalid: recapture it; do not describe the difference.
107
+ - Someone asks for orbit or turnaround renders painted from a 2D concept:
108
+ decline, and render real angles of the real mesh instead.
109
+
110
+ ## References
111
+
112
+ - [Geometry hash script](references/geometry-hash.mjs)
113
+ - [Asset workflow and `assets inspect`](https://github.com/auraoneai/aura3d/blob/main/docs/agents/asset-workflow.md)
114
+ - [Rendering proof rule](https://github.com/auraoneai/aura3d/blob/main/docs/agents/rendering-proof-required.md)
115
+ - Meshy retexture runs, approval, and `--max-credits`: load `meshy-cli`.
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ // Geometry-untouched proof for a retexture: hashes every mesh primitive's
3
+ // POSITION (and index) accessor bytes in a .glb, ignoring materials, images,
4
+ // and textures. Two GLBs whose "geometryHash" matches have byte-identical
5
+ // vertex positions and topology. Dependency-free; reads GLB 2.0 (BIN chunk,
6
+ // data: URIs, or relative buffer files). Draco-compressed meshes are rejected.
7
+ //
8
+ // Usage: node geometry-hash.mjs before.glb [after.glb]
9
+ import { createHash } from "node:crypto";
10
+ import { readFileSync } from "node:fs";
11
+ import { dirname, resolve } from "node:path";
12
+
13
+ function readGlb(path) {
14
+ const buf = readFileSync(path);
15
+ if (buf.readUInt32LE(0) !== 0x46546c67) throw new Error(`${path}: not a GLB (bad magic)`);
16
+ let offset = 12;
17
+ let json;
18
+ let bin;
19
+ while (offset < buf.length) {
20
+ const length = buf.readUInt32LE(offset);
21
+ const type = buf.readUInt32LE(offset + 4);
22
+ const chunk = buf.subarray(offset + 8, offset + 8 + length);
23
+ if (type === 0x4e4f534a) json = JSON.parse(chunk.toString("utf8"));
24
+ else if (type === 0x004e4942) bin = chunk;
25
+ offset += 8 + length;
26
+ }
27
+ if (!json) throw new Error(`${path}: missing JSON chunk`);
28
+ // buffer 0 is the BIN chunk unless it declares a uri; data: and relative uris are also read.
29
+ const buffers = (json.buffers ?? []).map((buffer, index) => {
30
+ if (!buffer.uri) return index === 0 ? bin : undefined;
31
+ if (buffer.uri.startsWith("data:")) return Buffer.from(buffer.uri.split(",")[1] ?? "", "base64");
32
+ if (/^[a-z]+:/i.test(buffer.uri)) throw new Error(`${path}: remote buffer uri not supported`);
33
+ return readFileSync(resolve(dirname(path), decodeURIComponent(buffer.uri)));
34
+ });
35
+ return { json, buffers };
36
+ }
37
+
38
+ const COMPONENT_BYTES = { 5120: 1, 5121: 1, 5122: 2, 5123: 2, 5125: 4, 5126: 4 };
39
+ const TYPE_COUNT = { SCALAR: 1, VEC2: 2, VEC3: 3, VEC4: 4, MAT4: 16 };
40
+
41
+ function accessorBytes({ json, buffers }, index) {
42
+ const accessor = json.accessors[index];
43
+ if (accessor.bufferView === undefined) return Buffer.alloc(0);
44
+ const view = json.bufferViews[accessor.bufferView];
45
+ const bin = buffers[view.buffer ?? 0];
46
+ if (!bin) throw new Error(`buffer ${view.buffer ?? 0} is not readable`);
47
+ const elementSize = COMPONENT_BYTES[accessor.componentType] * TYPE_COUNT[accessor.type];
48
+ const stride = view.byteStride ?? elementSize;
49
+ const start = (view.byteOffset ?? 0) + (accessor.byteOffset ?? 0);
50
+ const out = Buffer.alloc(elementSize * accessor.count);
51
+ for (let i = 0; i < accessor.count; i += 1) bin.copy(out, i * elementSize, start + i * stride, start + i * stride + elementSize);
52
+ return out;
53
+ }
54
+
55
+ function geometryReport(path) {
56
+ const glb = readGlb(path);
57
+ const whole = createHash("sha256");
58
+ const primitives = [];
59
+ (glb.json.meshes ?? []).forEach((mesh, meshIndex) => {
60
+ (mesh.primitives ?? []).forEach((primitive, primitiveIndex) => {
61
+ if (primitive.extensions?.KHR_draco_mesh_compression) throw new Error("Draco-compressed geometry: decode before hashing");
62
+ const position = primitive.attributes?.POSITION;
63
+ if (position === undefined) return;
64
+ const positions = accessorBytes(glb, position);
65
+ const indices = primitive.indices === undefined ? Buffer.alloc(0) : accessorBytes(glb, primitive.indices);
66
+ const hash = createHash("sha256").update(positions).update(indices).digest("hex");
67
+ whole.update(hash);
68
+ const accessor = glb.json.accessors[position];
69
+ primitives.push({ mesh: mesh.name ?? `mesh${meshIndex}`, primitive: primitiveIndex, vertices: accessor.count, min: accessor.min, max: accessor.max, hash: `sha256-${hash}` });
70
+ });
71
+ });
72
+ return { file: path, primitiveCount: primitives.length, geometryHash: `sha256-${whole.digest("hex")}`, primitives };
73
+ }
74
+
75
+ const [before, after] = process.argv.slice(2);
76
+ if (!before) {
77
+ console.error("usage: node geometry-hash.mjs before.glb [after.glb]");
78
+ process.exit(2);
79
+ }
80
+ const a = geometryReport(before);
81
+ if (!after) {
82
+ console.log(JSON.stringify(a, null, 2));
83
+ } else {
84
+ const b = geometryReport(after);
85
+ const geometryUntouched = a.geometryHash === b.geometryHash;
86
+ const changed = a.primitives.filter((p, i) => p.hash !== b.primitives[i]?.hash).map((p) => `${p.mesh}#${p.primitive}`);
87
+ console.log(JSON.stringify({ geometryUntouched, before: a.geometryHash, after: b.geometryHash, primitiveCount: [a.primitiveCount, b.primitiveCount], changed }, null, 2));
88
+ process.exitCode = geometryUntouched ? 0 : 1;
89
+ }
@@ -0,0 +1,132 @@
1
+ ---
2
+ name: aura3d-scene-authoring
3
+ description: Turns a scene prompt into editable `@aura3d/engine` source by picking a scene kit or prompt plan, compiling it, and repairing weak screenshots from the compiled report. Use when writing a scene or route from a prompt, choosing among `sceneKits.*`, `prefabs.*`, or `primitives.*`, or using `definePromptPlan`, `compilePromptPlan`, `promptPlanToScene`, or `collectAuraSceneEvidence`.
4
+ ---
5
+
6
+ # Aura3D scene authoring
7
+
8
+ You turn prompt intent into maintainable TypeScript that calls public Aura3D
9
+ APIs. There is no hidden scene generator. Every scene gets a look — the preset
10
+ that supplies environment light, key shadow, fog, background and grade. Shared
11
+ rules (claim labels, forbidden patterns, typed assets, benchmark mode) are in
12
+ [boundaries](../aura3d-core/references/boundaries.md).
13
+
14
+ ## Look target
15
+
16
+ Read the genre recipe row in `../aura3d-art-direction/references/look-recipes.md`,
17
+ pick the look id, and carry it through the plan and the code. A scene without a
18
+ look renders flat on a void.
19
+
20
+ ## Establish the contract
21
+
22
+ 1. Run `npx @aura3d/cli@latest --help` and use only the commands it prints.
23
+ 2. Read `src/aura-assets.ts` and `aura.assets.json`. Every subject model comes
24
+ from a generated key. If the prompt names a real object and no key exists,
25
+ load `aura3d-assets` first.
26
+ 3. Read the installed `@aura3d/engine` type declarations before naming an
27
+ export. The prompt-plan enums are narrow: `sceneType` is `product-viewer`,
28
+ `cinematic-scene`, `mini-game`, or `material-studio`.
29
+ 4. Decide the mode. Benchmark mode: if `aura3d look capture` is available,
30
+ run the look-dev loop; otherwise copy the smallest matching recipe, run
31
+ `npm install && npm run build`, return the runner-owned run command, stop,
32
+ and label the result `prototype`.
33
+
34
+ ## Procedure
35
+
36
+ 1. Restate the prompt as scene intent: subject, scene family, camera, lighting,
37
+ effects, interaction, and what a screenshot must visibly show.
38
+ 2. Pick the starting point in this order: a template, then a scene kit, then
39
+ `prefabs.*`, and `primitives.*` only for set dressing, guides, or explicitly
40
+ abstract visuals.
41
+
42
+ | Prompt family | Start from | Screenshot must show |
43
+ | --- | --- | --- |
44
+ | Physics playground | `sceneKits.physicsPlayground` | falling cubes, settled pile, ramp, contact cues, reset |
45
+ | Particle fountain | `sceneKits.particleFountain` | dense upward flow, nozzle, splash, a real emission-rate control |
46
+ | Solar system | `sceneKits.solarSystem` | sun glow, six attached planet labels, orbit paths, stars |
47
+ | Neon tunnel | `sceneKits.neonTunnel` | inside-tube view, receding rings, rails, controlled bloom |
48
+ | Data visualization | `sceneKits.dataViz` | bars, axes, ticks, title, legend, selected value |
49
+ | Mini golf | `sceneKits.miniGolf` | ball, cup, aim and power, score, obstacle, boundaries |
50
+ | Material lab | `sceneKits.materialLab` | material classes distinct in pixels, not labels |
51
+ | City block | `sceneKits.cityBlock` | buildings, lit windows, streets, a real day/night state |
52
+ | Humanoid walk | `sceneKits.humanoidWalk` | one connected humanoid, planted feet, path |
53
+ | Product viewer | `sceneKits.productViewer` | typed model on plinth, contact shadow, softboxes |
54
+
55
+ 3. Kit path: mount the kit once and keep its diagnostics.
56
+
57
+ ```ts
58
+ import { createAuraApp, sceneKits } from "@aura3d/engine";
59
+ import { assets } from "./aura-assets";
60
+
61
+ const kit = sceneKits.productViewer(assets.product);
62
+ createAuraApp("#app", kit.toAppOptions());
63
+ console.log(kit.diagnostics, kit.evidence);
64
+ ```
65
+
66
+ 4. Plan path, when the prompt is product intent rather than a kit family:
67
+
68
+ ```ts
69
+ import { compilePromptPlan, createAuraApp, definePromptPlan, promptPlanToScene } from "@aura3d/engine";
70
+ import { assets } from "./aura-assets";
71
+
72
+ const plan = definePromptPlan({
73
+ sceneType: "product-viewer",
74
+ subject: { asset: assets.product },
75
+ camera: { preset: "product-orbit" },
76
+ lighting: { preset: "studio-softbox" },
77
+ interaction: "orbit",
78
+ acceptanceCriteria: ["product is centered and recognizable"]
79
+ } as const);
80
+
81
+ const compiled = compilePromptPlan(plan);
82
+ createAuraApp("#app", { scene: promptPlanToScene(plan), diagnostics: { overlay: true } });
83
+ console.log(compiled.report.visualSystems, compiled.report.repairHints);
84
+ ```
85
+
86
+ 5. Read the compiled report before editing: `visualSystems` lists what the
87
+ compiled scene actually contains; `rejected` lists what the engine could
88
+ not do (each with a code such as `unsupported-effect`); `repairHints`
89
+ carries the `lookLint` findings; `negativeCriteria` lists what must not
90
+ ship. Repair from `repairHints` plus `aura3d look lint` output.
91
+ 6. Controls go through `ui.*` helpers and must change rendered pixels; CSS and
92
+ DOM are UI only and never stand in for particles, bloom, trails, labels, or
93
+ renderer output.
94
+ 7. Mount one app per route. Never dispose and recreate the app inside a frame
95
+ loop to animate values.
96
+ 8. Normal mode only: collect `collectAuraSceneEvidence(scene)` or the kit
97
+ evidence, run `npm run build`, and hand screenshots and route health to
98
+ `aura3d-evidence-review`. The template `npm run test` gate runs Playwright;
99
+ run it in CI or on a remote runner, not on the local machine.
100
+ 9. Weak screenshot: apply the repair hints (tighter framing, foreground and
101
+ background structure, key/fill/rim contrast, visible state) or switch back
102
+ to the matching kit before changing any label or claim.
103
+
104
+ ## Look-dev loop
105
+
106
+ `aura3d look capture` → judge against `quality-bar.md` → `aura3d look lint` →
107
+ one change per round (lint first, then the weakest category). Full loop spec:
108
+ `aura3d-art-direction`.
109
+
110
+ ## Stop and report
111
+
112
+ - The subject is a named real object with no typed asset key: stop, load
113
+ `aura3d-assets`, and label the scene `blocked` until the key exists.
114
+ - The only way to satisfy the prompt is a primitive stand-in for the primary
115
+ subject: stop and label it `prototype`.
116
+ - An effect, PBR, skinning, WebGPU, or postprocess claim has no pixel evidence
117
+ from a route importing only `@aura3d/engine`: drop the claim or label it
118
+ `prototype`.
119
+ - `npm run build` fails on an export you guessed: remove it and re-read the
120
+ type declarations. Do not add casts to force it through.
121
+ - Benchmark mode: stop after the build and report the runner-owned command.
122
+
123
+ ## References
124
+
125
+ - [Shared boundaries](../aura3d-core/references/boundaries.md)
126
+ - [Build playbook](https://github.com/auraoneai/aura3d/blob/main/docs/agents/build-playbook.md)
127
+ - [Prompt to 3D workflow](https://github.com/auraoneai/aura3d/blob/main/docs/agents/prompt-to-3d-workflow.md)
128
+ - [Benchmark recipes](https://github.com/auraoneai/aura3d/blob/main/docs/agents/benchmark-recipes.md)
129
+ - [Agent guide llms.txt](https://github.com/auraoneai/aura3d/blob/main/llms.txt)
130
+ - [Prompt recipes](https://aura3d.auraone.ai/docs/prompt-recipes.html)
131
+ - [Look recipes](../aura3d-art-direction/references/look-recipes.md)
132
+ - [Look by scene family](references/look-by-family.md)