create-aura3d 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 (396) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-skills.d.ts +38 -0
  3. package/dist/agent-skills.d.ts.map +1 -0
  4. package/dist/agent-skills.js +103 -0
  5. package/dist/agent-skills.js.map +1 -0
  6. package/dist/cli.js +32 -5
  7. package/dist/cli.js.map +1 -1
  8. package/dist/index.d.ts +32 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +52 -10
  11. package/dist/index.js.map +1 -1
  12. package/dist/showcase-spec-artifacts.d.ts +1 -1
  13. package/dist/showcase-spec-game-geometry-extractor.js +8 -11
  14. package/dist/showcase-spec-game-geometry-extractor.js.map +1 -1
  15. package/dist/template-hdri.d.ts +12 -0
  16. package/dist/template-hdri.d.ts.map +1 -0
  17. package/dist/template-hdri.js +49 -0
  18. package/dist/template-hdri.js.map +1 -0
  19. package/hdri/ATTRIBUTION.md +8 -0
  20. package/hdri/autumn_field_puresky_1k.hdr +0 -0
  21. package/hdri/kloppenheim_06_puresky_1k.hdr +0 -0
  22. package/hdri/night-2k.hdr +0 -0
  23. package/hdri/studio_small_08_1k.hdr +0 -0
  24. package/package.json +14 -10
  25. package/skills/agent-files/AGENTS.md +3 -0
  26. package/skills/aura3d-animation-studio/SKILL.md +153 -0
  27. package/skills/aura3d-animation-studio/references/shot-looks.md +26 -0
  28. package/skills/aura3d-art-direction/SKILL.md +84 -0
  29. package/skills/aura3d-art-direction/references/failure-gallery.md +64 -0
  30. package/skills/aura3d-art-direction/references/framing-and-shots.md +45 -0
  31. package/skills/aura3d-art-direction/references/look-recipes.md +32 -0
  32. package/skills/aura3d-art-direction/references/quality-bar.md +103 -0
  33. package/skills/aura3d-art-direction/references/reference-frames.md +82 -0
  34. package/skills/aura3d-assets/SKILL.md +132 -0
  35. package/skills/aura3d-assets/references/preview-under-look.md +26 -0
  36. package/skills/aura3d-browser-game/SKILL.md +127 -0
  37. package/skills/aura3d-browser-game/references/genre-looks.md +52 -0
  38. package/skills/aura3d-character-animation/SKILL.md +129 -0
  39. package/skills/aura3d-character-animation/references/stage-and-lighting.md +31 -0
  40. package/skills/aura3d-core/SKILL.md +121 -0
  41. package/skills/aura3d-core/references/boundaries.md +91 -0
  42. package/skills/aura3d-evidence-review/SKILL.md +106 -0
  43. package/skills/aura3d-game-art/SKILL.md +118 -0
  44. package/skills/aura3d-game-art/references/sheet-check.mjs +58 -0
  45. package/skills/aura3d-game-art/references/sprite-palettes.md +25 -0
  46. package/skills/aura3d-materials-environments/SKILL.md +139 -0
  47. package/skills/aura3d-performance/SKILL.md +97 -0
  48. package/skills/aura3d-retexture/SKILL.md +115 -0
  49. package/skills/aura3d-retexture/references/geometry-hash.mjs +89 -0
  50. package/skills/aura3d-scene-authoring/SKILL.md +132 -0
  51. package/skills/aura3d-scene-authoring/references/look-by-family.md +28 -0
  52. package/skills/aura3d-threejs-migration/SKILL.md +125 -0
  53. package/skills/aura3d-threejs-migration/references/look-mapping.md +27 -0
  54. package/skills/llms.txt +117 -0
  55. package/skills/manifest.json +163 -0
  56. package/skills/meshy-cli/SKILL.md +133 -0
  57. package/templates/animation-channel/.claude/CLAUDE.md +3 -0
  58. package/templates/animation-channel/.github/workflows/aura3d-lookdev.yml +67 -0
  59. package/templates/animation-channel/AGENTS.md +3 -0
  60. package/templates/animation-channel/package.json +3 -2
  61. package/templates/animation-channel/src/main.ts +5 -6
  62. package/templates/animation-channel/src/render-plan.ts +5 -3
  63. package/templates/animation-channel/tests/look-floor.ts +270 -0
  64. package/templates/animation-channel/tests/route-health.spec.ts +1 -1
  65. package/templates/animation-channel/tests/screenshot.spec.ts +10 -5
  66. package/templates/animation-channel/vite.config.ts +7 -0
  67. package/templates/animation-studio/.claude/CLAUDE.md +3 -0
  68. package/templates/animation-studio/.github/workflows/aura3d-lookdev.yml +67 -0
  69. package/templates/animation-studio/AGENTS.md +2 -70
  70. package/templates/animation-studio/package.json +4 -3
  71. package/templates/animation-studio/scripts/build-clip-library.ts +6 -5
  72. package/templates/animation-studio/scripts/resolve-asset.ts +7 -4
  73. package/templates/animation-studio/src/scene-player.ts +6 -6
  74. package/templates/animation-studio/src/set-templates.ts +13 -9
  75. package/templates/animation-studio/tests/look-floor.ts +270 -0
  76. package/templates/animation-studio/tests/route-health.spec.ts +2 -2
  77. package/templates/animation-studio/tests/screenshot.spec.ts +18 -10
  78. package/templates/animation-studio/vite.config.ts +2 -0
  79. package/templates/architecture-interior/.claude/CLAUDE.md +3 -0
  80. package/templates/architecture-interior/.github/workflows/aura3d-lookdev.yml +67 -0
  81. package/templates/architecture-interior/AGENTS.md +3 -0
  82. package/templates/architecture-interior/README.md +16 -0
  83. package/templates/architecture-interior/aura.assets.json +24 -0
  84. package/templates/architecture-interior/package.json +24 -0
  85. package/templates/architecture-interior/public/aura-assets/kenneyModularDungeonRoomSmall.a7e74a5f.glb +0 -0
  86. package/templates/architecture-interior/src/aura-assets.ts +16 -0
  87. package/templates/architecture-interior/src/main.ts +23 -0
  88. package/templates/architecture-interior/tests/look-floor.ts +270 -0
  89. package/templates/{three-compat-architecture-interior → architecture-interior}/tests/route-health.spec.ts +3 -3
  90. package/templates/architecture-interior/tests/screenshot.spec.ts +21 -0
  91. package/templates/architecture-interior/vite.config.ts +7 -0
  92. package/templates/arena-shooter/.claude/CLAUDE.md +3 -0
  93. package/templates/arena-shooter/.github/workflows/aura3d-lookdev.yml +67 -0
  94. package/templates/arena-shooter/AGENTS.md +3 -0
  95. package/templates/arena-shooter/README.md +45 -0
  96. package/templates/arena-shooter/aura.assets.json +62 -0
  97. package/templates/arena-shooter/index.html +32 -0
  98. package/templates/arena-shooter/package.json +23 -0
  99. package/templates/arena-shooter/playwright.config.ts +15 -0
  100. package/templates/arena-shooter/public/aura-assets/craft_miner.de323205.glb +0 -0
  101. package/templates/arena-shooter/public/aura-assets/craft_racer.bce8cb3d.glb +0 -0
  102. package/templates/arena-shooter/public/aura-assets/meteor_detailed.f30379ab.glb +0 -0
  103. package/templates/arena-shooter/src/aura-assets.ts +56 -0
  104. package/templates/arena-shooter/src/main.ts +616 -0
  105. package/templates/arena-shooter/tests/look-floor.ts +270 -0
  106. package/templates/arena-shooter/tests/playable.spec.ts +56 -0
  107. package/templates/arena-shooter/tests/route-health.spec.ts +87 -0
  108. package/templates/arena-shooter/tests/screenshot.spec.ts +22 -0
  109. package/templates/arena-shooter/tsconfig.json +15 -0
  110. package/templates/arena-shooter/vite.config.ts +7 -0
  111. package/templates/asset-inspector/.claude/CLAUDE.md +3 -0
  112. package/templates/asset-inspector/.github/workflows/aura3d-lookdev.yml +67 -0
  113. package/templates/asset-inspector/AGENTS.md +3 -0
  114. package/templates/asset-inspector/README.md +13 -0
  115. package/templates/asset-inspector/aura.assets.json +24 -0
  116. package/templates/{three-compat-custom-threejs-migration → asset-inspector}/package.json +5 -3
  117. package/templates/asset-inspector/public/aura-assets/kenneyCarKitSedanSports.2889c428.glb +0 -0
  118. package/templates/asset-inspector/src/aura-assets.ts +16 -0
  119. package/templates/asset-inspector/src/main.ts +23 -0
  120. package/templates/asset-inspector/tests/look-floor.ts +270 -0
  121. package/templates/{three-compat-character-viewer → asset-inspector}/tests/route-health.spec.ts +3 -3
  122. package/templates/asset-inspector/tests/screenshot.spec.ts +21 -0
  123. package/templates/asset-inspector/vite.config.ts +7 -0
  124. package/templates/character-controller/.claude/CLAUDE.md +3 -0
  125. package/templates/character-controller/.github/workflows/aura3d-lookdev.yml +67 -0
  126. package/templates/character-controller/AGENTS.md +3 -0
  127. package/templates/character-controller/README.md +7 -1
  128. package/templates/character-controller/aura.assets.json +29 -22
  129. package/templates/character-controller/index.html +4 -5
  130. package/templates/character-controller/package.json +5 -4
  131. package/templates/character-controller/public/aura-assets/auraclash-player-rig.glb +0 -0
  132. package/templates/character-controller/src/aura-assets.ts +25 -7
  133. package/templates/character-controller/src/main.ts +190 -47
  134. package/templates/character-controller/tests/certified-rig.spec.ts +2 -2
  135. package/templates/character-controller/tests/look-floor.ts +270 -0
  136. package/templates/character-controller/tests/route-health.spec.ts +31 -6
  137. package/templates/character-controller/tests/screenshot.spec.ts +17 -5
  138. package/templates/character-controller/vite.config.ts +7 -0
  139. package/templates/character-viewer/.claude/CLAUDE.md +3 -0
  140. package/templates/character-viewer/.github/workflows/aura3d-lookdev.yml +67 -0
  141. package/templates/character-viewer/AGENTS.md +3 -0
  142. package/templates/character-viewer/README.md +13 -0
  143. package/templates/character-viewer/aura.assets.json +24 -0
  144. package/templates/{three-compat-asset-inspector → character-viewer}/package.json +5 -3
  145. package/templates/character-viewer/public/aura-assets/kenneyMiniForestCharacterArcher.0fd0f92e.glb +0 -0
  146. package/templates/character-viewer/src/aura-assets.ts +16 -0
  147. package/templates/character-viewer/src/main.ts +21 -0
  148. package/templates/character-viewer/tests/look-floor.ts +270 -0
  149. package/templates/{three-compat-custom-threejs-migration → character-viewer}/tests/route-health.spec.ts +3 -3
  150. package/templates/character-viewer/tests/screenshot.spec.ts +21 -0
  151. package/templates/character-viewer/vite.config.ts +7 -0
  152. package/templates/cinematic-scene/.claude/CLAUDE.md +3 -0
  153. package/templates/cinematic-scene/.github/workflows/aura3d-lookdev.yml +67 -0
  154. package/templates/cinematic-scene/AGENTS.md +3 -0
  155. package/templates/cinematic-scene/README.md +11 -2
  156. package/templates/cinematic-scene/package.json +3 -2
  157. package/templates/cinematic-scene/src/main.ts +30 -7
  158. package/templates/cinematic-scene/tests/look-floor.ts +270 -0
  159. package/templates/cinematic-scene/tests/route-health.spec.ts +31 -3
  160. package/templates/cinematic-scene/tests/screenshot.spec.ts +34 -45
  161. package/templates/cinematic-scene/vite.config.ts +7 -0
  162. package/templates/custom-scene/.claude/CLAUDE.md +3 -0
  163. package/templates/custom-scene/.github/workflows/aura3d-lookdev.yml +67 -0
  164. package/templates/custom-scene/AGENTS.md +3 -0
  165. package/templates/custom-scene/README.md +13 -0
  166. package/templates/custom-scene/aura.assets.json +24 -0
  167. package/templates/{three-compat-character-viewer → custom-scene}/package.json +5 -3
  168. package/templates/custom-scene/public/aura-assets/kenneyPirateKitShipMedium.279ea019.glb +0 -0
  169. package/templates/custom-scene/src/aura-assets.ts +16 -0
  170. package/templates/custom-scene/src/main.ts +23 -0
  171. package/templates/custom-scene/tests/look-floor.ts +270 -0
  172. package/templates/{three-compat-asset-inspector → custom-scene}/tests/route-health.spec.ts +3 -3
  173. package/templates/custom-scene/tests/screenshot.spec.ts +21 -0
  174. package/templates/custom-scene/vite.config.ts +7 -0
  175. package/templates/episode-builder/.claude/CLAUDE.md +3 -0
  176. package/templates/episode-builder/.github/workflows/aura3d-lookdev.yml +67 -0
  177. package/templates/episode-builder/AGENTS.md +3 -0
  178. package/templates/episode-builder/package.json +3 -2
  179. package/templates/episode-builder/src/main.ts +5 -3
  180. package/templates/episode-builder/src/render-plan.ts +5 -3
  181. package/templates/episode-builder/tests/look-floor.ts +270 -0
  182. package/templates/episode-builder/tests/screenshot.spec.ts +10 -4
  183. package/templates/episode-builder/vite.config.ts +7 -0
  184. package/templates/falling-blocks-starter/.claude/CLAUDE.md +3 -0
  185. package/templates/falling-blocks-starter/.github/workflows/aura3d-lookdev.yml +67 -0
  186. package/templates/falling-blocks-starter/AGENTS.md +3 -0
  187. package/templates/falling-blocks-starter/README.md +10 -1
  188. package/templates/falling-blocks-starter/aura.assets.json +40 -23
  189. package/templates/falling-blocks-starter/package.json +3 -2
  190. package/templates/falling-blocks-starter/public/aura-assets/quaternius-cube-crate.glb +0 -0
  191. package/templates/falling-blocks-starter/public/aura-assets/quaternius-wall-modular.glb +0 -0
  192. package/templates/falling-blocks-starter/src/aura-assets.ts +33 -10
  193. package/templates/falling-blocks-starter/src/main.ts +316 -117
  194. package/templates/falling-blocks-starter/tests/look-floor.ts +270 -0
  195. package/templates/falling-blocks-starter/tests/playable.spec.ts +51 -18
  196. package/templates/falling-blocks-starter/tests/route-health.spec.ts +17 -7
  197. package/templates/falling-blocks-starter/tests/screenshot.spec.ts +21 -0
  198. package/templates/falling-blocks-starter/vite.config.ts +7 -0
  199. package/templates/fighting-game/.claude/CLAUDE.md +3 -0
  200. package/templates/fighting-game/.github/workflows/aura3d-lookdev.yml +67 -0
  201. package/templates/fighting-game/AGENTS.md +3 -0
  202. package/templates/fighting-game/README.md +2 -0
  203. package/templates/fighting-game/aura.assets.json +56 -46
  204. package/templates/fighting-game/package.json +4 -2
  205. package/templates/fighting-game/public/aura-assets/auraclash-player-rig.glb +0 -0
  206. package/templates/fighting-game/public/aura-assets/auraclash-rival-rig.glb +0 -0
  207. package/templates/fighting-game/src/aura-assets.ts +54 -20
  208. package/templates/fighting-game/src/game/fighters.ts +57 -12
  209. package/templates/fighting-game/src/main.ts +135 -53
  210. package/templates/fighting-game/tests/certified-rig.spec.ts +1 -1
  211. package/templates/fighting-game/tests/gameplay-smoke.spec.ts +2 -8
  212. package/templates/fighting-game/tests/look-floor.ts +270 -0
  213. package/templates/fighting-game/tests/route-health.spec.ts +12 -4
  214. package/templates/fighting-game/tests/screenshot.spec.ts +10 -4
  215. package/templates/fighting-game/vite.config.ts +7 -0
  216. package/templates/large-scene/.claude/CLAUDE.md +3 -0
  217. package/templates/large-scene/.github/workflows/aura3d-lookdev.yml +67 -0
  218. package/templates/large-scene/AGENTS.md +3 -0
  219. package/templates/large-scene/README.md +13 -0
  220. package/templates/large-scene/aura.assets.json +40 -0
  221. package/templates/{three-compat-architecture-interior → large-scene}/package.json +5 -3
  222. package/templates/large-scene/public/aura-assets/kenneyMiniForestRocksHigh.226728a0.glb +0 -0
  223. package/templates/large-scene/public/aura-assets/kenneyMiniForestTree.0075d505.glb +0 -0
  224. package/templates/large-scene/src/aura-assets.ts +28 -0
  225. package/templates/large-scene/src/main.ts +43 -0
  226. package/templates/large-scene/tests/look-floor.ts +270 -0
  227. package/templates/large-scene/tests/route-health.spec.ts +16 -0
  228. package/templates/large-scene/tests/screenshot.spec.ts +21 -0
  229. package/templates/large-scene/vite.config.ts +7 -0
  230. package/templates/material-authoring/.claude/CLAUDE.md +3 -0
  231. package/templates/material-authoring/.github/workflows/aura3d-lookdev.yml +67 -0
  232. package/templates/material-authoring/AGENTS.md +3 -0
  233. package/templates/material-authoring/README.md +15 -0
  234. package/templates/material-authoring/aura.assets.json +24 -0
  235. package/templates/material-authoring/package.json +24 -0
  236. package/templates/material-authoring/public/aura-assets/kenneyCarKitSedanSports.2889c428.glb +0 -0
  237. package/templates/material-authoring/src/aura-assets.ts +16 -0
  238. package/templates/material-authoring/src/main.ts +78 -0
  239. package/templates/material-authoring/tests/look-floor.ts +270 -0
  240. package/templates/material-authoring/tests/route-health.spec.ts +16 -0
  241. package/templates/material-authoring/tests/screenshot.spec.ts +21 -0
  242. package/templates/material-authoring/vite.config.ts +7 -0
  243. package/templates/mini-game/.claude/CLAUDE.md +3 -0
  244. package/templates/mini-game/.github/workflows/aura3d-lookdev.yml +67 -0
  245. package/templates/mini-game/AGENTS.md +3 -0
  246. package/templates/mini-game/README.md +9 -6
  247. package/templates/mini-game/aura.assets.json +177 -36
  248. package/templates/mini-game/package.json +3 -1
  249. package/templates/mini-game/public/aura-assets/kaykit-barbarian.glb +0 -0
  250. package/templates/mini-game/public/aura-assets/kenneyPlatformerKitKey.2e930961.glb +0 -0
  251. package/templates/mini-game/public/aura-assets/kenneyPlatformerKitStar.a102a1b9.glb +0 -0
  252. package/templates/mini-game/public/aura-assets/quaternius-crate.glb +0 -0
  253. package/templates/mini-game/public/aura-assets/quaternius-cube-crate.glb +0 -0
  254. package/templates/mini-game/src/aura-assets.ts +140 -32
  255. package/templates/mini-game/src/main.ts +204 -71
  256. package/templates/mini-game/tests/certified-rig.spec.ts +2 -2
  257. package/templates/mini-game/tests/look-floor.ts +270 -0
  258. package/templates/mini-game/tests/playable.spec.ts +23 -2
  259. package/templates/mini-game/tests/route-health.spec.ts +2 -2
  260. package/templates/mini-game/tests/screenshot.spec.ts +44 -53
  261. package/templates/mini-game/vite.config.ts +7 -0
  262. package/templates/postprocess-scene/.claude/CLAUDE.md +3 -0
  263. package/templates/postprocess-scene/.github/workflows/aura3d-lookdev.yml +67 -0
  264. package/templates/postprocess-scene/AGENTS.md +3 -0
  265. package/templates/postprocess-scene/README.md +17 -0
  266. package/templates/postprocess-scene/aura.assets.json +38 -0
  267. package/templates/postprocess-scene/package.json +24 -0
  268. package/templates/postprocess-scene/public/aura-assets/showcaseLuma.ef389217.glb +0 -0
  269. package/templates/postprocess-scene/public/aura-assets/showcaseMiko.fcdc2b75.glb +0 -0
  270. package/templates/postprocess-scene/src/aura-assets.ts +28 -0
  271. package/templates/postprocess-scene/src/main.ts +29 -0
  272. package/templates/postprocess-scene/tests/look-floor.ts +270 -0
  273. package/templates/postprocess-scene/tests/route-health.spec.ts +16 -0
  274. package/templates/postprocess-scene/tests/screenshot.spec.ts +21 -0
  275. package/templates/postprocess-scene/vite.config.ts +7 -0
  276. package/templates/premium-product-viewer/.claude/CLAUDE.md +3 -0
  277. package/templates/premium-product-viewer/.github/workflows/aura3d-lookdev.yml +67 -0
  278. package/templates/premium-product-viewer/AGENTS.md +3 -0
  279. package/templates/premium-product-viewer/README.md +18 -0
  280. package/templates/premium-product-viewer/aura.assets.json +24 -0
  281. package/templates/premium-product-viewer/package.json +24 -0
  282. package/templates/premium-product-viewer/public/aura-assets/khronosToyCar.01a60862.glb +0 -0
  283. package/templates/premium-product-viewer/src/aura-assets.ts +16 -0
  284. package/templates/premium-product-viewer/src/main.ts +33 -0
  285. package/templates/premium-product-viewer/tests/look-floor.ts +270 -0
  286. package/templates/premium-product-viewer/tests/route-health.spec.ts +16 -0
  287. package/templates/premium-product-viewer/tests/screenshot.spec.ts +21 -0
  288. package/templates/premium-product-viewer/vite.config.ts +7 -0
  289. package/templates/product-viewer/.claude/CLAUDE.md +3 -0
  290. package/templates/product-viewer/.github/workflows/aura3d-lookdev.yml +67 -0
  291. package/templates/product-viewer/AGENTS.md +3 -0
  292. package/templates/product-viewer/README.md +10 -8
  293. package/templates/product-viewer/package.json +3 -1
  294. package/templates/product-viewer/src/aura-assets.ts +1 -1
  295. package/templates/product-viewer/src/main.ts +78 -19
  296. package/templates/product-viewer/tests/look-floor.ts +270 -0
  297. package/templates/product-viewer/tests/route-health.spec.ts +19 -1
  298. package/templates/product-viewer/tests/screenshot.spec.ts +35 -41
  299. package/templates/product-viewer/vite.config.ts +7 -0
  300. package/templates/prompt-animation-channel/.claude/CLAUDE.md +3 -0
  301. package/templates/prompt-animation-channel/.github/workflows/aura3d-lookdev.yml +67 -0
  302. package/templates/prompt-animation-channel/AGENTS.md +3 -0
  303. package/templates/prompt-animation-channel/package.json +3 -2
  304. package/templates/prompt-animation-channel/src/main.ts +5 -3
  305. package/templates/prompt-animation-channel/src/render-plan.ts +5 -3
  306. package/templates/prompt-animation-channel/tests/look-floor.ts +270 -0
  307. package/templates/prompt-animation-channel/tests/route-health.spec.ts +1 -1
  308. package/templates/prompt-animation-channel/tests/screenshot.spec.ts +10 -4
  309. package/templates/prompt-animation-channel/tests/storyboard-playback.spec.ts +1 -1
  310. package/templates/prompt-animation-channel/vite.config.ts +7 -0
  311. package/templates/racing-starter/.claude/CLAUDE.md +3 -0
  312. package/templates/racing-starter/.github/workflows/aura3d-lookdev.yml +67 -0
  313. package/templates/racing-starter/AGENTS.md +3 -0
  314. package/templates/racing-starter/README.md +8 -6
  315. package/templates/racing-starter/package.json +3 -2
  316. package/templates/racing-starter/src/main.ts +168 -146
  317. package/templates/racing-starter/tests/geometry-certification.json +34 -0
  318. package/templates/racing-starter/tests/look-floor.ts +270 -0
  319. package/templates/racing-starter/tests/playable.spec.ts +63 -80
  320. package/templates/racing-starter/tests/route-health.spec.ts +14 -12
  321. package/templates/racing-starter/tests/screenshot.spec.ts +21 -0
  322. package/templates/racing-starter/vite.config.ts +7 -0
  323. package/templates/character-controller/public/aura-assets/showcaseWalkAnimatedGirl.93872fc2.glb +0 -0
  324. package/templates/character-controller/public/aura-assets/showcaseWalkAnimatedGirl.thumb.svg +0 -1
  325. package/templates/falling-blocks-starter/public/aura-assets/showcaseBlockfallCabinet.679d52fe.glb +0 -0
  326. package/templates/falling-blocks-starter/public/aura-assets/showcaseBlockfallCabinet.thumb.svg +0 -1
  327. package/templates/fighting-game/public/aura-assets/showcaseRunnerRobot.252b3a16.glb +0 -0
  328. package/templates/fighting-game/public/aura-assets/showcaseRunnerRobot.thumb.svg +0 -1
  329. package/templates/fighting-game/public/aura-assets/showcaseWalkAnimatedGirl.93872fc2.glb +0 -0
  330. package/templates/fighting-game/public/aura-assets/showcaseWalkAnimatedGirl.thumb.svg +0 -1
  331. package/templates/mini-game/public/aura-assets/showcaseKenneyOobiPlatformerHero.3f821141.glb +0 -0
  332. package/templates/mini-game/public/aura-assets/showcaseKenneyOobiPlatformerHero.thumb.svg +0 -1
  333. package/templates/three-compat-architecture-interior/aura.assets.json +0 -7
  334. package/templates/three-compat-architecture-interior/src/aura-assets.ts +0 -3
  335. package/templates/three-compat-architecture-interior/src/main.ts +0 -27
  336. package/templates/three-compat-architecture-interior/tests/screenshot.spec.ts +0 -15
  337. package/templates/three-compat-asset-inspector/aura.assets.json +0 -7
  338. package/templates/three-compat-asset-inspector/src/aura-assets.ts +0 -3
  339. package/templates/three-compat-asset-inspector/src/main.ts +0 -17
  340. package/templates/three-compat-asset-inspector/tests/screenshot.spec.ts +0 -15
  341. package/templates/three-compat-character-viewer/aura.assets.json +0 -7
  342. package/templates/three-compat-character-viewer/src/aura-assets.ts +0 -3
  343. package/templates/three-compat-character-viewer/src/main.ts +0 -17
  344. package/templates/three-compat-character-viewer/tests/screenshot.spec.ts +0 -15
  345. package/templates/three-compat-custom-threejs-migration/aura.assets.json +0 -7
  346. package/templates/three-compat-custom-threejs-migration/src/aura-assets.ts +0 -3
  347. package/templates/three-compat-custom-threejs-migration/src/main.ts +0 -16
  348. package/templates/three-compat-custom-threejs-migration/tests/screenshot.spec.ts +0 -15
  349. package/templates/three-compat-large-scene/aura.assets.json +0 -7
  350. package/templates/three-compat-large-scene/package.json +0 -22
  351. package/templates/three-compat-large-scene/src/aura-assets.ts +0 -3
  352. package/templates/three-compat-large-scene/src/main.ts +0 -31
  353. package/templates/three-compat-large-scene/tests/route-health.spec.ts +0 -16
  354. package/templates/three-compat-large-scene/tests/screenshot.spec.ts +0 -15
  355. package/templates/three-compat-material-authoring/aura.assets.json +0 -7
  356. package/templates/three-compat-material-authoring/package.json +0 -22
  357. package/templates/three-compat-material-authoring/src/aura-assets.ts +0 -3
  358. package/templates/three-compat-material-authoring/src/main.ts +0 -33
  359. package/templates/three-compat-material-authoring/tests/route-health.spec.ts +0 -16
  360. package/templates/three-compat-material-authoring/tests/screenshot.spec.ts +0 -15
  361. package/templates/three-compat-postprocess-scene/aura.assets.json +0 -7
  362. package/templates/three-compat-postprocess-scene/package.json +0 -22
  363. package/templates/three-compat-postprocess-scene/src/aura-assets.ts +0 -3
  364. package/templates/three-compat-postprocess-scene/src/main.ts +0 -17
  365. package/templates/three-compat-postprocess-scene/tests/route-health.spec.ts +0 -16
  366. package/templates/three-compat-postprocess-scene/tests/screenshot.spec.ts +0 -15
  367. package/templates/three-compat-premium-product-viewer/aura.assets.json +0 -7
  368. package/templates/three-compat-premium-product-viewer/package.json +0 -22
  369. package/templates/three-compat-premium-product-viewer/src/aura-assets.ts +0 -3
  370. package/templates/three-compat-premium-product-viewer/src/main.ts +0 -18
  371. package/templates/three-compat-premium-product-viewer/tests/route-health.spec.ts +0 -16
  372. package/templates/three-compat-premium-product-viewer/tests/screenshot.spec.ts +0 -15
  373. /package/templates/{three-compat-architecture-interior → architecture-interior}/index.html +0 -0
  374. /package/templates/{three-compat-architecture-interior → architecture-interior}/playwright.config.ts +0 -0
  375. /package/templates/{three-compat-architecture-interior → architecture-interior}/tsconfig.json +0 -0
  376. /package/templates/{three-compat-asset-inspector → asset-inspector}/index.html +0 -0
  377. /package/templates/{three-compat-asset-inspector → asset-inspector}/playwright.config.ts +0 -0
  378. /package/templates/{three-compat-asset-inspector → asset-inspector}/tsconfig.json +0 -0
  379. /package/templates/{three-compat-character-viewer → character-viewer}/index.html +0 -0
  380. /package/templates/{three-compat-character-viewer → character-viewer}/playwright.config.ts +0 -0
  381. /package/templates/{three-compat-character-viewer → character-viewer}/tsconfig.json +0 -0
  382. /package/templates/{three-compat-custom-threejs-migration → custom-scene}/index.html +0 -0
  383. /package/templates/{three-compat-custom-threejs-migration → custom-scene}/playwright.config.ts +0 -0
  384. /package/templates/{three-compat-custom-threejs-migration → custom-scene}/tsconfig.json +0 -0
  385. /package/templates/{three-compat-large-scene → large-scene}/index.html +0 -0
  386. /package/templates/{three-compat-large-scene → large-scene}/playwright.config.ts +0 -0
  387. /package/templates/{three-compat-large-scene → large-scene}/tsconfig.json +0 -0
  388. /package/templates/{three-compat-material-authoring → material-authoring}/index.html +0 -0
  389. /package/templates/{three-compat-material-authoring → material-authoring}/playwright.config.ts +0 -0
  390. /package/templates/{three-compat-material-authoring → material-authoring}/tsconfig.json +0 -0
  391. /package/templates/{three-compat-postprocess-scene → postprocess-scene}/index.html +0 -0
  392. /package/templates/{three-compat-postprocess-scene → postprocess-scene}/playwright.config.ts +0 -0
  393. /package/templates/{three-compat-postprocess-scene → postprocess-scene}/tsconfig.json +0 -0
  394. /package/templates/{three-compat-premium-product-viewer → premium-product-viewer}/index.html +0 -0
  395. /package/templates/{three-compat-premium-product-viewer → premium-product-viewer}/playwright.config.ts +0 -0
  396. /package/templates/{three-compat-premium-product-viewer → premium-product-viewer}/tsconfig.json +0 -0
@@ -0,0 +1,270 @@
1
+ /**
2
+ * PRD-13 T3.12/T3.13 — the shared template look floor.
3
+ *
4
+ * Every create-aura3d template's `tests/screenshot.spec.ts` calls
5
+ * `assertTemplateLookFloor(page, ...)` after readiness: the same five checks
6
+ * everywhere (PRD §6.5/T3.12):
7
+ *
8
+ * 1. non-blank — sampled WebGL pixels are lit and varied (not a uniform
9
+ * clear/void frame);
10
+ * 2. `diagnostics().look.lint` carries no `severity === "error"` finding
11
+ * (empty when A3D_QR_LOOKS is off — the check never silently skips);
12
+ * 3. `appliedLook.environment.specularIntensity > 0` — an environment map
13
+ * actually reached the frame;
14
+ * 4. `appliedLook.shadows.strength >= 0.8` when the look declares a shadow
15
+ * caster (a null ShadowReport means the renderer produced no shadow
16
+ * evidence — recorded, not failed);
17
+ * 5. `appliedLook.pixelRatio >= min(devicePixelRatio, tierCap)` — the
18
+ * renderer used the display density up to the tier cap (2).
19
+ *
20
+ * …plus the optional §T3.12 subject check: the lit-pixel bounding box of the
21
+ * canvas' central region must sit within `tolerance` of the expected subject
22
+ * bounds (default ±10% of frame).
23
+ *
24
+ * Templates that mount through `createAuraApp` surface `appliedLook`/`look`
25
+ * via the global `__AURA3D_LIVE_APPS__` registry — no per-template wiring.
26
+ * `skipAppDiagnostics` covers the bespoke-renderer template (animation-studio),
27
+ * which reports its stage environment through its own readiness evidence.
28
+ */
29
+
30
+ import { expect, type Page } from "@playwright/test";
31
+
32
+ /** Normalized canvas-space bounds the lit subject mass is expected to occupy. */
33
+ export interface LookFloorSubjectBounds {
34
+ readonly x: number;
35
+ readonly y: number;
36
+ readonly width: number;
37
+ readonly height: number;
38
+ }
39
+
40
+ export interface LookFloorOptions {
41
+ /** Expected subject bounds in normalized canvas units. Omit to skip. */
42
+ readonly subject?: LookFloorSubjectBounds;
43
+ /** Fractional tolerance on each bound axis. Default 0.1 (±10%). */
44
+ readonly tolerance?: number;
45
+ /** Template has no `__AURA3D_LIVE_APPS__` app (bespoke renderer). */
46
+ readonly skipAppDiagnostics?: boolean;
47
+ }
48
+
49
+ export interface LookFloorReport {
50
+ readonly sampledPixels: number;
51
+ readonly brightPixels: number;
52
+ readonly uniqueBuckets: number;
53
+ readonly subjectBounds: LookFloorSubjectBounds | null;
54
+ readonly appliedLook: {
55
+ readonly specularIntensity: number;
56
+ readonly shadowStrength: number | null;
57
+ readonly pixelRatio: number;
58
+ readonly renderPath: string;
59
+ readonly background: string | null;
60
+ } | null;
61
+ readonly lookLintErrors: readonly string[];
62
+ readonly devicePixelRatio: number;
63
+ }
64
+
65
+ const MIN_BRIGHT_FRACTION = 0.02;
66
+ const MIN_UNIQUE_BUCKETS = 8;
67
+
68
+ export async function assertTemplateLookFloor(page: Page, options: LookFloorOptions = {}): Promise<LookFloorReport> {
69
+ const canvas = page.locator("canvas").first();
70
+ await expect(canvas).toBeVisible();
71
+
72
+ /*
73
+ * Deterministic frame before profiling: pause every live app, rewind its
74
+ * runtime clock and step a fixed 45 frames at 1/60 — through `stepAsync`,
75
+ * not the synchronous registry `settle()`. The production renderer mounts
76
+ * asynchronously, so a sync step loop renders nothing while the mount is in
77
+ * flight and never yields for it to finish (the failure mode on software-GL
78
+ * runners: blank frames, `environment.intensity` still NaN in diagnostics).
79
+ * Awaiting each step also lets pending environment/IBL/asset promises resolve
80
+ * between frames, and one final dt=0 step re-renders the same simulated
81
+ * instant once that work has applied.
82
+ */
83
+ const report = await page.evaluate(async (): Promise<LookFloorReport> => {
84
+ interface LiveApp {
85
+ pause?: () => void;
86
+ resetRuntimeClock?: () => void;
87
+ step?: (dt?: number) => void;
88
+ stepAsync?: (dt?: number) => Promise<unknown>;
89
+ diagnostics?: () => Record<string, unknown>;
90
+ }
91
+ const empty = (code: string): LookFloorReport => ({
92
+ sampledPixels: 0,
93
+ brightPixels: 0,
94
+ uniqueBuckets: 0,
95
+ subjectBounds: null,
96
+ appliedLook: null,
97
+ lookLintErrors: [code],
98
+ devicePixelRatio: globalThis.devicePixelRatio ?? 1
99
+ });
100
+ const registry = (globalThis as { __AURA3D_LIVE_APPS__?: { all?: () => readonly LiveApp[] } }).__AURA3D_LIVE_APPS__;
101
+ const apps = [...(registry?.all?.() ?? [])];
102
+ const stepApp = async (app: LiveApp, dt: number): Promise<void> => {
103
+ if (app.stepAsync) {
104
+ try {
105
+ await Promise.race([
106
+ app.stepAsync(dt),
107
+ new Promise((resolvePromise) => setTimeout(resolvePromise, 30_000))
108
+ ]);
109
+ return;
110
+ } catch {
111
+ // synchronous step fallback below
112
+ }
113
+ }
114
+ app.step?.(dt);
115
+ };
116
+ /*
117
+ * Wall-clock bound on the settle loop: on software-GL CI runners a single
118
+ * stepped render of a heavy scene costs several seconds, so an unbounded
119
+ * 45-step loop outlives the test budget and fails with a bare timeout and
120
+ * no report. Cap the stepping and always take the dt=0 settle frame — a
121
+ * partially settled scene still yields a readable floor report.
122
+ */
123
+ const STEP_WALLCLOCK_BUDGET_MS = 420_000;
124
+ const settleStartedAt = Date.now();
125
+ for (const app of apps) {
126
+ app.pause?.();
127
+ app.resetRuntimeClock?.();
128
+ for (let index = 0; index < 45; index += 1) {
129
+ if (Date.now() - settleStartedAt > STEP_WALLCLOCK_BUDGET_MS) break;
130
+ await stepApp(app, 1 / 60);
131
+ }
132
+ await stepApp(app, 0);
133
+ }
134
+ /*
135
+ * Renderers outside the liveApps registry (bespoke renderers, e.g.
136
+ * animation-studio's A3DRenderer) cannot be stepped. Two animation
137
+ * frames guarantee at least one full app render finished inside this
138
+ * evaluate task, so the readPixels below sees a real presented frame
139
+ * instead of a compositor-cleared buffer.
140
+ */
141
+ if (apps.length === 0) {
142
+ await new Promise<void>((resolve) => {
143
+ requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
144
+ });
145
+ }
146
+
147
+ const diagnostics = apps[0]?.diagnostics?.() as
148
+ | { appliedLook?: { environment?: { specularIntensity?: number; background?: string }; shadows?: { strength?: number | null } | null; pixelRatio?: number; renderPath?: string }; look?: { lint?: readonly { severity?: string; code?: string }[] } }
149
+ | undefined;
150
+ const appliedLook = diagnostics?.appliedLook
151
+ ? {
152
+ specularIntensity: diagnostics.appliedLook.environment?.specularIntensity ?? 0,
153
+ shadowStrength: diagnostics.appliedLook.shadows?.strength ?? null,
154
+ pixelRatio: diagnostics.appliedLook.pixelRatio ?? 0,
155
+ renderPath: diagnostics.appliedLook.renderPath ?? "unknown",
156
+ background: diagnostics.appliedLook.environment?.background ?? null
157
+ }
158
+ : null;
159
+ const lookLintErrors = (diagnostics?.look?.lint ?? [])
160
+ .filter((finding) => finding.severity === "error")
161
+ .map((finding) => finding.code ?? "unknown");
162
+ const devicePixelRatio = globalThis.devicePixelRatio ?? 1;
163
+
164
+ /*
165
+ * The app's WebGL context is not preserveDrawingBuffer, so readPixels must
166
+ * run in the same task as the stepped render, before compositing clears the
167
+ * drawing buffer. That also removes the composited element screenshot that
168
+ * software-GL runners could not produce inside a test timeout.
169
+ */
170
+ const target = [...document.querySelectorAll("canvas")]
171
+ .map((element) => ({
172
+ element,
173
+ gl: (element.getContext("webgl2") ?? element.getContext("webgl")) as WebGL2RenderingContext | WebGLRenderingContext | null
174
+ }))
175
+ .find((entry) => entry.gl !== null);
176
+ if (!target?.gl) return { ...empty("no-webgl-context"), appliedLook, lookLintErrors };
177
+ const gl = target.gl;
178
+ const width = gl.drawingBufferWidth;
179
+ const height = gl.drawingBufferHeight;
180
+ if (width === 0 || height === 0) return { ...empty("empty-drawing-buffer"), appliedLook, lookLintErrors };
181
+ // readPixels reads the currently bound framebuffer: renderers that end a
182
+ // frame with an offscreen target bound (shadow/post FBOs — e.g.
183
+ // animation-studio's bespoke renderer) would return that target's pixels
184
+ // instead of the canvas backbuffer. Rebind the default framebuffer first;
185
+ // every renderer rebinds its own targets at the start of its next frame.
186
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
187
+ const pixels = new Uint8Array(width * height * 4);
188
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
189
+
190
+ const BRIGHT_LUMA = 48;
191
+ const stride = 4; // pixels — 16×16 sample grid
192
+ let sampled = 0;
193
+ let bright = 0;
194
+ const buckets = new Set<number>();
195
+ // Central-region lit-pixel bbox: edges carry floor/backdrop, the subject
196
+ // mass is what every §6.4 template frames mid-frame.
197
+ const x0 = Math.floor(width * 0.1);
198
+ const x1 = Math.floor(width * 0.9);
199
+ const y0 = Math.floor(height * 0.1);
200
+ const y1 = Math.floor(height * 0.9);
201
+ let minX = Number.POSITIVE_INFINITY;
202
+ let maxX = Number.NEGATIVE_INFINITY;
203
+ let minY = Number.POSITIVE_INFINITY;
204
+ let maxY = Number.NEGATIVE_INFINITY;
205
+ for (let y = 0; y < height; y += stride) {
206
+ for (let x = 0; x < width; x += stride) {
207
+ const offset = (y * width + x) * 4;
208
+ const r = pixels[offset] ?? 0;
209
+ const g = pixels[offset + 1] ?? 0;
210
+ const b = pixels[offset + 2] ?? 0;
211
+ sampled += 1;
212
+ buckets.add(((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4));
213
+ const luma = 0.2126 * r + 0.7152 * g + 0.0722 * b;
214
+ if (luma > BRIGHT_LUMA) {
215
+ bright += 1;
216
+ if (x >= x0 && x <= x1 && y >= y0 && y <= y1) {
217
+ minX = Math.min(minX, x);
218
+ maxX = Math.max(maxX, x);
219
+ minY = Math.min(minY, y);
220
+ maxY = Math.max(maxY, y);
221
+ }
222
+ }
223
+ }
224
+ }
225
+ // readPixels rows run bottom-up; report `y` in the same top-down
226
+ // convention the composited-screenshot path produced so stored
227
+ // expectations stay comparable across the switch.
228
+ const subjectBounds = Number.isFinite(minX)
229
+ ? { x: minX / width, y: 1 - maxY / height, width: (maxX - minX) / width, height: (maxY - minY) / height }
230
+ : null;
231
+
232
+ return {
233
+ sampledPixels: sampled,
234
+ brightPixels: bright,
235
+ uniqueBuckets: buckets.size,
236
+ subjectBounds,
237
+ appliedLook,
238
+ lookLintErrors,
239
+ devicePixelRatio
240
+ };
241
+ });
242
+
243
+ // 1. Non-blank.
244
+ expect(report.brightPixels / Math.max(1, report.sampledPixels)).toBeGreaterThan(MIN_BRIGHT_FRACTION);
245
+ expect(report.uniqueBuckets).toBeGreaterThan(MIN_UNIQUE_BUCKETS);
246
+
247
+ if (!options.skipAppDiagnostics) {
248
+ // 2–5. Renderer/look evidence via __AURA3D_LIVE_APPS__.
249
+ expect(report.appliedLook, "appliedLook diagnostics missing — is the app mounted via createAuraApp?").not.toBeNull();
250
+ expect(report.lookLintErrors).toEqual([]);
251
+ expect(report.appliedLook!.specularIntensity).toBeGreaterThan(0);
252
+ if (report.appliedLook!.shadowStrength !== null) {
253
+ expect(report.appliedLook!.shadowStrength!).toBeGreaterThanOrEqual(0.8);
254
+ }
255
+ expect(report.appliedLook!.pixelRatio).toBeGreaterThanOrEqual(Math.min(report.devicePixelRatio, 2));
256
+ }
257
+
258
+ // 6. Subject bounds ±10%.
259
+ if (options.subject) {
260
+ const tolerance = options.tolerance ?? 0.1;
261
+ const measured = `measured ${JSON.stringify(report.subjectBounds)}`;
262
+ expect(report.subjectBounds, "no lit subject mass in the central frame").not.toBeNull();
263
+ expect(Math.abs(report.subjectBounds!.x - options.subject.x), measured).toBeLessThanOrEqual(tolerance);
264
+ expect(Math.abs(report.subjectBounds!.y - options.subject.y), measured).toBeLessThanOrEqual(tolerance);
265
+ expect(Math.abs(report.subjectBounds!.width - options.subject.width), measured).toBeLessThanOrEqual(tolerance);
266
+ expect(Math.abs(report.subjectBounds!.height - options.subject.height), measured).toBeLessThanOrEqual(tolerance);
267
+ }
268
+
269
+ return report;
270
+ }
@@ -0,0 +1,16 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { expect, test } from "@playwright/test";
4
+
5
+ test.setTimeout(240_000);
6
+
7
+ test("Aura3D migration template reaches ready state", async ({ page }) => {
8
+ await page.goto("/");
9
+ await expect.poll(() => page.locator("body").getAttribute("data-aura3d-ready"), { timeout: 150_000 }).toBe("true");
10
+ const drawCalls = Number(await page.locator("body").getAttribute("data-aura3d-draw-calls"));
11
+ const diagnostics = await page.evaluate(() => (window as unknown as { __AURA3D_ROUTE_READY__?: { diagnostics?: { backend?: string } } }).__AURA3D_ROUTE_READY__?.diagnostics);
12
+ expect(diagnostics?.backend).toBe("webgl2");
13
+ expect(drawCalls).toBeGreaterThan(0);
14
+ mkdirSync(resolve("tests/reports"), { recursive: true });
15
+ writeFileSync(resolve("tests/reports/route-health.json"), `${JSON.stringify({ ready: true, backend: diagnostics?.backend, drawCalls }, null, 2)}\n`);
16
+ });
@@ -0,0 +1,21 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { expect, test } from "@playwright/test";
4
+ import { assertTemplateLookFloor } from "./look-floor";
5
+
6
+ test.setTimeout(600_000);
7
+
8
+ // PRD-13 T3.12 — look floor: non-blank, look.lint error-free, appliedLook
9
+ // environment specular > 0, shadow strength >= 0.8, pixelRatio at tier cap,
10
+ // subject bounds within ±10% — plus this template's bespoke assertions.
11
+ test("Aura3D three compat premium product viewer screenshot clears the look floor", async ({ page }) => {
12
+ await page.goto("/");
13
+ await expect.poll(() => page.locator("body").getAttribute("data-aura3d-ready"), { timeout: 150_000 }).toBe("true");
14
+
15
+ const floor = await assertTemplateLookFloor(page, { subject: { x: 0.25, y: 0.3, width: 0.5, height: 0.5 } });
16
+ const screenshot = await page.screenshot({ fullPage: false });
17
+ mkdirSync(resolve("tests/reports"), { recursive: true });
18
+ writeFileSync(resolve("tests/reports/screenshot.png"), screenshot);
19
+ writeFileSync(resolve("tests/reports/screenshot.json"), `${JSON.stringify({ bytes: screenshot.byteLength, floor }, null, 2)}\n`);
20
+ expect(screenshot.byteLength).toBeGreaterThan(1000);
21
+ });
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from "vite";
2
+ import { auraDecodersPlugin } from "@aura3d/assets/vite";
3
+
4
+ // F-05-04 (05-PKG): ship + serve the decoder vendor tree at /aura-decoders/
5
+ // so compressed (KTX2/draco/meshopt) GLBs decode same-origin with correct
6
+ // MIME in both `vite dev` and `vite preview`/deployed builds.
7
+ export default defineConfig({ plugins: [auraDecodersPlugin()] });
@@ -0,0 +1,3 @@
1
+ # Aura3D agent instructions
2
+
3
+ Read ./llms.txt first. Read the `aura3d-art-direction` skill. Every scene gets a look. Run the look-dev loop (`aura3d look capture` → judge → iterate) before calling a scene done.
@@ -0,0 +1,67 @@
1
+ name: Aura3D look-dev
2
+
3
+ # Captures this scene's screenshot tests on an Apple-silicon GPU runner
4
+ # (ANGLE Metal) and uploads the report as the `lookdev` artifact.
5
+ # `aura3d look capture --runner gh-actions` dispatches this workflow and
6
+ # downloads the artifacts; it can also be run manually from the Actions tab.
7
+ # No secrets are used; workflow_dispatch only — never runs forked code.
8
+
9
+ on:
10
+ workflow_dispatch:
11
+ inputs:
12
+ shots:
13
+ description: "Shot names to capture (comma-separated; the template's defaults when empty)"
14
+ required: false
15
+ default: ""
16
+ viewports:
17
+ description: "Viewport names (comma-separated; the template's defaults when empty)"
18
+ required: false
19
+ default: ""
20
+
21
+ permissions:
22
+ contents: read
23
+
24
+ jobs:
25
+ capture:
26
+ name: Look-dev captures (macos-14, ANGLE Metal)
27
+ runs-on: macos-14
28
+ timeout-minutes: 45
29
+ env:
30
+ QRC_GPU_ARGS: "--use-angle=metal --enable-gpu --ignore-gpu-blocklist"
31
+ A3D_LOOKDEV_SHOTS: ${{ inputs.shots }}
32
+ A3D_LOOKDEV_VIEWPORTS: ${{ inputs.viewports }}
33
+ steps:
34
+ - name: Checkout
35
+ uses: actions/checkout@v4
36
+ with:
37
+ lfs: false
38
+
39
+ - name: Setup Node.js
40
+ uses: actions/setup-node@v4
41
+ with:
42
+ node-version: '22'
43
+ cache: 'npm'
44
+
45
+ - name: Install dependencies
46
+ run: npm ci
47
+
48
+ - name: Build the app
49
+ run: npm run build
50
+
51
+ - name: Install Playwright Chromium
52
+ run: npx playwright install chromium
53
+
54
+ - name: Capture screenshots
55
+ run: npx playwright test tests/screenshot.spec.ts --reporter=line
56
+ env:
57
+ CHROMIUM_FLAGS: ${{ env.QRC_GPU_ARGS }}
58
+
59
+ - name: Upload look-dev artifacts
60
+ if: always()
61
+ uses: actions/upload-artifact@v4
62
+ with:
63
+ name: lookdev
64
+ path: |
65
+ tests/reports/**
66
+ if-no-files-found: warn
67
+ retention-days: 30
@@ -0,0 +1,3 @@
1
+ # Aura3D agent instructions
2
+
3
+ Read ./llms.txt first. Read the `aura3d-art-direction` skill. Every scene gets a look. Run the look-dev loop (`aura3d look capture` → judge → iterate) before calling a scene done.
@@ -1,7 +1,6 @@
1
1
  # Aura3D Product Viewer
2
2
 
3
- Agent-friendly product scene starter using the public `@aura3d/lean/product`
4
- API.
3
+ Agent-friendly product scene starter on the public `@aura3d/engine` API.
5
4
 
6
5
  ```bash
7
6
  npm install
@@ -10,9 +9,12 @@ npx @aura3d/cli@latest assets add ./assets/product.glb --name product
10
9
  npm run test
11
10
  ```
12
11
 
13
- Edit `src/main.ts` to change the camera, material, studio environment, plinth,
14
- typed product, and diagnostics. Do not
15
- invent asset paths; after `assets add`, use `assets.product` from
16
- `src/aura-assets.ts`. The default scene composes the product, plinth, floor,
17
- studio environment, and orbit interaction directly through the lean product
18
- entry. It does not install physics, navigation, editor, or Node-media systems.
12
+ Edit `src/main.ts` to change the camera, plinth, typed product, and diagnostics.
13
+ Do not invent asset paths; after `assets add`, use `assets.product` from
14
+ `src/aura-assets.ts`.
15
+
16
+ The default scene composes the product on a plinth under the `product-studio`
17
+ look (studio HDRI, key light, neutral backdrop, grade) with `camera.frameAsset`
18
+ orbit autoframing — the subject fills 45–70% of frame height. Orbit interaction
19
+ is the only pointer control. It does not install physics, navigation, editor,
20
+ or Node-media systems.
@@ -11,10 +11,12 @@
11
11
  "test": "playwright test tests/route-health.spec.ts tests/screenshot.spec.ts --workers=1"
12
12
  },
13
13
  "dependencies": {
14
- "@aura3d/lean": "3.0.1"
14
+ "@aura3d/engine": "4.0.0",
15
+ "@aura3d/assets": "4.0.0"
15
16
  },
16
17
  "devDependencies": {
17
18
  "@playwright/test": "1.59.1",
19
+ "@types/node": "^22.15.30",
18
20
  "typescript": "^5.8.3",
19
21
  "vite": "^7.3.2"
20
22
  }
@@ -1,4 +1,4 @@
1
- import { defineAuraAssets } from "@aura3d/lean/product";
1
+ import { defineAuraAssets } from "@aura3d/engine";
2
2
 
3
3
  export const assets = defineAuraAssets({
4
4
  product: {
@@ -1,40 +1,99 @@
1
+ // Product viewer: a typed GLB on a plinth under the `product-studio` look
2
+ // (studio HDRI + key light + neutral backdrop + contrast grade), framed by
3
+ // camera.frameAsset — the orbit autoframe that fits the product at 45–70% of
4
+ // frame height. Orbit interaction is the only pointer control.
1
5
  import {
2
6
  camera,
3
7
  createAuraApp,
4
- environments,
5
8
  interactions,
9
+ looks,
6
10
  material,
7
11
  model,
8
12
  primitives,
9
13
  scene
10
- } from "@aura3d/lean/product";
14
+ } from "@aura3d/engine";
11
15
  import { assets } from "./aura-assets";
12
16
 
13
- // PART C2 game-ready adoption: the plinth wears the @aura3d/materials
14
- // "carPaint" preset shell (clearcoat 1 + flake normal scale) in a pearl studio
15
- // base, and the floor carries the "glassThin" preset color/roughness values as
16
- // a glass display deck (transmission itself lives in the full engine API).
17
- const carPaintPlinth = material.clearcoatPaint({ color: "#d7dce2", roughness: 0.3, metallic: 0.55, clearcoat: 1 });
18
- const glassThinDeck = material.pbr({ color: "#9fc6d4", roughness: 0.08, metallic: 0 });
17
+ declare global {
18
+ interface Window {
19
+ __AURA3D_PRODUCT_VIEWER__?: ProductViewerEvidence;
20
+ __AURA3D_ROUTE_READY__?: unknown;
21
+ }
22
+ }
23
+
24
+ interface ProductViewerEvidence {
25
+ readonly look: { readonly id: string; readonly category: string };
26
+ readonly camera: {
27
+ readonly mode: string;
28
+ readonly fov: number;
29
+ readonly distance: number;
30
+ readonly subjectHeightFraction: readonly [number, number];
31
+ readonly orbit: boolean;
32
+ };
33
+ readonly product: { readonly assetId: string; readonly url: string; readonly metres: readonly [number, number, number] };
34
+ readonly evidence: { readonly entry: string };
35
+ }
36
+
37
+ const LOOK_ID = "product-studio" as const;
38
+
39
+ // The look supplies the studio backdrop, HDRI environment and key light; the
40
+ // scene adds only the plinth/deck and the typed product — no adoption-preset
41
+ // material shells, ambient/fill overrides, or .background() calls.
42
+ const plinthMaterial = material.pbr({ color: "#3a3f47", roughness: 0.34, metalness: 0.4 });
43
+ const deckMaterial = material.pbr({ color: "#24272e", roughness: 0.62, metalness: 0.1 });
44
+
45
+ // frameAsset fits the product to ~1/padding of frame height; padding 1.6 puts
46
+ // the subject at ~60% — inside the look's 45–70% framing band.
47
+ const autoframe = camera.frameAsset(assets.product, {
48
+ targetHeight: 1.62,
49
+ padding: 1.6,
50
+ fov: 32,
51
+ azimuth: 0.62,
52
+ elevation: 0.28,
53
+ position: [0, 0.18, -0.62]
54
+ });
19
55
 
20
56
  const productScene = scene()
21
- .background("#071018")
22
- .add(primitives.plane({ name: "glass deck floor", material: glassThinDeck })
23
- .position(0, -0.05, -0.62).scale([6.2, 1, 5.2]))
24
- .add(primitives.box({ name: "carPaint product plinth", material: carPaintPlinth })
25
- .position(0, 0.06, -0.62).scale([1.82, 0.18, 1.4]))
26
- .add(model(assets.product, { name: "typed studio product" }).position(0, 1.08, -0.62).scale(0.66))
27
- .add(environments.studio())
28
- .add(interactions.orbit())
29
- .camera(camera.perspective({ position: [2.65, 2.05, 4.55], target: [0, 1.02, -0.62], fov: 32 }));
57
+ .add(looks.preset(LOOK_ID))
58
+ .add(
59
+ primitives.plane({ name: "studio deck floor", material: deckMaterial })
60
+ .position(0, -0.05, -0.62)
61
+ .scale([6.2, 1, 5.2])
62
+ )
63
+ .add(
64
+ primitives.box({ name: "product plinth", material: plinthMaterial })
65
+ .position(0, 0.06, -0.62)
66
+ .scale([1.82, 0.18, 1.4])
67
+ )
68
+ .add(
69
+ model(assets.product, { name: "typed studio product", castShadow: true })
70
+ .position(0, 1.08, -0.62)
71
+ .scale(0.66)
72
+ )
73
+ .add(interactions.orbit({ target: "typed studio product" }))
74
+ .camera(autoframe);
30
75
 
31
76
  const app = createAuraApp("#app", { scene: productScene });
77
+
78
+ window.__AURA3D_PRODUCT_VIEWER__ = {
79
+ look: { id: LOOK_ID, category: looks.describe(LOOK_ID).category },
80
+ camera: {
81
+ mode: autoframe.mode,
82
+ fov: autoframe.fov ?? 32,
83
+ distance: autoframe.distance ?? 0,
84
+ subjectHeightFraction: [0.45, 0.7],
85
+ orbit: true
86
+ },
87
+ product: { assetId: assets.product.id, url: assets.product.url, metres: assets.product.bounds },
88
+ evidence: { entry: "@aura3d/engine" }
89
+ };
90
+
32
91
  void app.ready().then(() => {
33
92
  const diagnostics = app.diagnostics();
34
93
  document.body.dataset.aura3dReady = "true";
35
- document.body.dataset.aura3dRuntimeBackend = diagnostics.runtimeBackend;
94
+ document.body.dataset.aura3dRuntimeBackend = diagnostics.backend;
36
95
  document.body.dataset.aura3dDrawCalls = String(diagnostics.drawCalls);
37
- (window as unknown as { __AURA3D_ROUTE_READY__?: unknown }).__AURA3D_ROUTE_READY__ = { ready: true, diagnostics };
96
+ window.__AURA3D_ROUTE_READY__ = { ready: true, diagnostics };
38
97
  }).catch((error: unknown) => {
39
98
  document.body.dataset.aura3dError = error instanceof Error ? error.message : String(error);
40
99
  });