create-aura3d 1.0.10 → 1.1.1

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 (61) hide show
  1. package/dist/cli.js +0 -0
  2. package/package.json +2 -2
  3. package/templates/cartoon-channel/README.md +38 -0
  4. package/templates/cartoon-channel/aura.assets.json +1364 -0
  5. package/templates/cartoon-channel/package.json +3 -2
  6. package/templates/cartoon-channel/public/aura-assets/luma.047f5e5f.glb +0 -0
  7. package/templates/cartoon-channel/public/aura-assets/luma.thumb.svg +1 -0
  8. package/templates/cartoon-channel/public/aura-assets/miko.047f5e5f.glb +0 -0
  9. package/templates/cartoon-channel/public/aura-assets/miko.thumb.svg +1 -0
  10. package/templates/cartoon-channel/public/aura-assets/moon-garden-feature-frame.png +0 -0
  11. package/templates/cartoon-channel/src/aura-assets.ts +5 -11
  12. package/templates/cartoon-channel/src/concept-episode-2-5d.css +159 -0
  13. package/templates/cartoon-channel/src/concept-episode-2-5d.ts +155 -0
  14. package/templates/cartoon-channel/src/image-puppet-episode.css +290 -0
  15. package/templates/cartoon-channel/src/image-puppet-episode.ts +139 -0
  16. package/templates/cartoon-channel/src/main.ts +89 -71
  17. package/templates/cartoon-channel/src/puppet-episode-2d.css +526 -0
  18. package/templates/cartoon-channel/src/puppet-episode-2d.ts +189 -0
  19. package/templates/cartoon-channel/src/render-plan.ts +1 -1
  20. package/templates/cartoon-channel/src/sample-episode-visual.css +457 -0
  21. package/templates/cartoon-channel/src/sample-episode-visual.ts +185 -0
  22. package/templates/cartoon-channel/test-results/.last-run.json +4 -0
  23. package/templates/cartoon-channel/tests/concept-2-5d-animation.spec.ts +18 -0
  24. package/templates/cartoon-channel/tests/concept-2-5d.spec.ts +30 -0
  25. package/templates/cartoon-channel/tests/image-puppet-animation.spec.ts +18 -0
  26. package/templates/cartoon-channel/tests/image-puppet.spec.ts +29 -0
  27. package/templates/cartoon-channel/tests/puppet-2d-animation.spec.ts +18 -0
  28. package/templates/cartoon-channel/tests/puppet-2d.spec.ts +26 -0
  29. package/templates/cartoon-channel/tests/reports/prompt-animation/cartoon-sample-episode.png +0 -0
  30. package/templates/cartoon-channel/tests/sample-episode-visual.spec.ts +45 -0
  31. package/templates/cartoon-channel/tests/storyboard-playback.spec.ts +1 -1
  32. package/templates/cartoon-studio/README.md +36 -0
  33. package/templates/cartoon-studio/aura.assets.json +157 -0
  34. package/templates/cartoon-studio/package-lock.json +2251 -0
  35. package/templates/cartoon-studio/package.json +13 -2
  36. package/templates/cartoon-studio/public/aura-assets/luma.047f5e5f.glb +0 -0
  37. package/templates/cartoon-studio/public/aura-assets/luma.humanoid-fixture.glb +0 -0
  38. package/templates/cartoon-studio/public/aura-assets/luma.thumb.svg +1 -0
  39. package/templates/cartoon-studio/public/aura-assets/miko.047f5e5f.glb +0 -0
  40. package/templates/cartoon-studio/public/aura-assets/miko.thumb.svg +1 -0
  41. package/templates/cartoon-studio/public/aura-assets/moonGarden.gltf +183 -0
  42. package/templates/cartoon-studio/scripts/episode.ts +276 -0
  43. package/templates/cartoon-studio/src/aura-assets.ts +55 -8
  44. package/templates/cartoon-studio/src/characters.ts +38 -1
  45. package/templates/cartoon-studio/src/episode-renderer.ts +605 -0
  46. package/templates/cartoon-studio/src/episode.ts +12 -6
  47. package/templates/cartoon-studio/src/main.ts +109 -41
  48. package/templates/cartoon-studio/src/render-plan.ts +162 -0
  49. package/templates/cartoon-studio/src/review.ts +99 -0
  50. package/templates/cartoon-studio/test-results/.last-run.json +4 -0
  51. package/templates/cartoon-studio/tests/episode-render.spec.ts +44 -0
  52. package/templates/cartoon-studio/tests/motion-quality.spec.ts +45 -0
  53. package/templates/cartoon-studio/tests/storyboard-playback.spec.ts +18 -10
  54. package/templates/cartoon-studio/tests/visual-review.spec.ts +21 -0
  55. package/templates/cinematic-scene/package.json +1 -1
  56. package/templates/episode-builder/package.json +1 -1
  57. package/templates/fighting-game/package.json +1 -1
  58. package/templates/mini-game/package.json +1 -1
  59. package/templates/product-viewer/package.json +1 -1
  60. package/templates/product-viewer/tests/screenshot.spec.ts +8 -16
  61. package/templates/prompt-cartoon-channel/package.json +1 -1
@@ -0,0 +1,18 @@
1
+ import { expect, test } from "@playwright/test";
2
+
3
+ test("image-puppet animation recording lane cannot produce release-facing proof", async ({ page }) => {
4
+ await page.goto("/?view=image-puppet&sampleTime=24");
5
+
6
+ await expect(page.locator("#sample-episode-visual")).toBeVisible();
7
+ await expect(page.locator("#image-puppet-episode")).toHaveCount(0);
8
+
9
+ const proof = await page.evaluate(() => ({
10
+ rejectedViews: (window as unknown as {
11
+ __AURA3D_CARTOON_TEMPLATE__?: { readonly rejectedViews?: readonly string[]; readonly rejectedViewReason?: string };
12
+ }).__AURA3D_CARTOON_TEMPLATE__?.rejectedViews ?? [],
13
+ imagePuppetProof: (window as unknown as { __AURA3D_CARTOON_IMAGE_PUPPET_PROOF__?: unknown }).__AURA3D_CARTOON_IMAGE_PUPPET_PROOF__
14
+ }));
15
+
16
+ expect(proof.imagePuppetProof).toBeUndefined();
17
+ expect(proof.rejectedViews).toContain("image-puppet");
18
+ });
@@ -0,0 +1,29 @@
1
+ import { expect, test } from "@playwright/test";
2
+
3
+ test("image-puppet query is kept as rejected evidence and does not mount a cutout route", async ({ page }) => {
4
+ await page.setViewportSize({ width: 1440, height: 900 });
5
+ await page.goto("/?view=image-puppet&sampleTime=24");
6
+
7
+ await expect(page.locator("#sample-episode-visual")).toBeVisible();
8
+ await expect(page.locator("#image-puppet-episode")).toHaveCount(0);
9
+ await expect(page.locator("[data-source-cutout]")).toHaveCount(0);
10
+
11
+ const quarantine = await page.evaluate(() => ({
12
+ imagePuppetProof: (window as unknown as { __AURA3D_CARTOON_IMAGE_PUPPET_PROOF__?: unknown }).__AURA3D_CARTOON_IMAGE_PUPPET_PROOF__,
13
+ sampleProof: (window as unknown as { __AURA3D_CARTOON_SAMPLE_EPISODE__?: { visualLayer?: { renderedBy?: string } } })
14
+ .__AURA3D_CARTOON_SAMPLE_EPISODE__,
15
+ template: (window as unknown as {
16
+ __AURA3D_CARTOON_TEMPLATE__?: {
17
+ readonly releaseFacingViews?: readonly string[];
18
+ readonly rejectedViews?: readonly string[];
19
+ readonly rejectedViewReason?: string;
20
+ };
21
+ }).__AURA3D_CARTOON_TEMPLATE__
22
+ }));
23
+
24
+ expect(quarantine.imagePuppetProof).toBeUndefined();
25
+ expect(quarantine.sampleProof?.visualLayer?.renderedBy).toBe("aura3d-scene");
26
+ expect(quarantine.template?.releaseFacingViews).toEqual(["sample-episode-visual"]);
27
+ expect(quarantine.template?.rejectedViews).toContain("image-puppet");
28
+ expect(quarantine.template?.rejectedViewReason).toMatch(/still-image|flat cutout|notTrue3D/i);
29
+ });
@@ -0,0 +1,18 @@
1
+ import { expect, test } from "@playwright/test";
2
+
3
+ test("2D puppet recording lane remains negative evidence only", async ({ page }) => {
4
+ await page.goto("/?view=puppet-2d&sampleTime=24");
5
+
6
+ await expect(page.locator("#sample-episode-visual")).toBeVisible();
7
+ await expect(page.locator("#puppet-episode-2d")).toHaveCount(0);
8
+
9
+ const proof = await page.evaluate(() => ({
10
+ rejectedViews: (window as unknown as {
11
+ __AURA3D_CARTOON_TEMPLATE__?: { readonly rejectedViews?: readonly string[]; readonly rejectedViewReason?: string };
12
+ }).__AURA3D_CARTOON_TEMPLATE__?.rejectedViews ?? [],
13
+ puppetProof: (window as unknown as { __AURA3D_CARTOON_2D_PUPPET_PROOF__?: unknown }).__AURA3D_CARTOON_2D_PUPPET_PROOF__
14
+ }));
15
+
16
+ expect(proof.puppetProof).toBeUndefined();
17
+ expect(proof.rejectedViews).toContain("puppet-2d");
18
+ });
@@ -0,0 +1,26 @@
1
+ import { expect, test } from "@playwright/test";
2
+
3
+ test("2D puppet query is quarantined from release-facing cartoon-channel proof", async ({ page }) => {
4
+ await page.setViewportSize({ width: 1440, height: 900 });
5
+ await page.goto("/?view=puppet-2d&sampleTime=24");
6
+
7
+ await expect(page.locator("#sample-episode-visual")).toBeVisible();
8
+ await expect(page.locator("#puppet-episode-2d")).toHaveCount(0);
9
+ await expect(page.locator(".puppet-robot")).toHaveCount(0);
10
+
11
+ const quarantine = await page.evaluate(() => ({
12
+ puppetProof: (window as unknown as { __AURA3D_CARTOON_2D_PUPPET_PROOF__?: unknown }).__AURA3D_CARTOON_2D_PUPPET_PROOF__,
13
+ template: (window as unknown as {
14
+ __AURA3D_CARTOON_TEMPLATE__?: {
15
+ readonly releaseFacingViews?: readonly string[];
16
+ readonly rejectedViews?: readonly string[];
17
+ readonly rejectedViewReason?: string;
18
+ };
19
+ }).__AURA3D_CARTOON_TEMPLATE__
20
+ }));
21
+
22
+ expect(quarantine.puppetProof).toBeUndefined();
23
+ expect(quarantine.template?.releaseFacingViews).toEqual(["sample-episode-visual"]);
24
+ expect(quarantine.template?.rejectedViews).toContain("puppet-2d");
25
+ expect(quarantine.template?.rejectedViewReason).toMatch(/still-image|cutout|animation readiness/i);
26
+ });
@@ -0,0 +1,45 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { dirname, resolve } from "node:path";
3
+ import { expect, test } from "@playwright/test";
4
+
5
+ test("sample episode visual renders a reviewable cartoon frame", async ({ page }) => {
6
+ await page.setViewportSize({ width: 1440, height: 900 });
7
+ await page.goto("/?sampleTime=24");
8
+
9
+ const frame = page.locator("#sample-episode-visual");
10
+ await expect(frame).toBeVisible();
11
+ await expect(page.locator("[data-sample-caption]")).toContainText(/tiny circle|stones|cleanup/i);
12
+
13
+ const proof = await page.evaluate(() => window.__AURA3D_CARTOON_SAMPLE_EPISODE__);
14
+ expect(proof?.episodeId).toBe("moon-garden-cleanup-001");
15
+ expect(proof?.sample.shotId).toBe("shot-glow-stone-teamwork");
16
+ expect(proof?.visualLayer.characters).toEqual(["miko", "luma"]);
17
+ expect(proof?.visualLayer.screenshotTarget).toBe("#sample-episode-visual");
18
+ expect(proof?.visualLayer.styleGuide).toMatch(/cartoon/i);
19
+ expect(proof?.visualLayer.renderedBy).toBe("aura3d-scene");
20
+ expect(proof?.visualLayer.usesTypedAssets).toBe(true);
21
+ await expect(frame).toHaveAttribute("data-uses-typed-assets", "true");
22
+ await expect(page.locator(".cartoon-robot").first()).toBeHidden();
23
+
24
+ const box = await frame.boundingBox();
25
+ expect(box?.width).toBeGreaterThan(900);
26
+ expect(box?.height).toBeGreaterThan(500);
27
+
28
+ const screenshot = await frame.screenshot({ animations: "disabled" });
29
+ expect(screenshot.byteLength).toBeGreaterThan(40_000);
30
+
31
+ const outputPath = resolve(findWorkspaceRoot(process.cwd()), "tests/reports/prompt-animation/cartoon-sample-episode.png");
32
+ mkdirSync(dirname(outputPath), { recursive: true });
33
+ writeFileSync(outputPath, screenshot);
34
+ });
35
+
36
+ function findWorkspaceRoot(start: string) {
37
+ let current = start;
38
+ for (let depth = 0; depth < 8; depth += 1) {
39
+ if (existsSync(resolve(current, "pnpm-workspace.yaml"))) return current;
40
+ const parent = resolve(current, "..");
41
+ if (parent === current) break;
42
+ current = parent;
43
+ }
44
+ return start;
45
+ }
@@ -2,7 +2,7 @@ import { expect, test } from "@playwright/test";
2
2
 
3
3
  test("cartoon channel storyboard caption renders", async ({ page }) => {
4
4
  await page.goto("/");
5
- await expect(page.getByText(/Aura3D cartoon channel|moon|robot/i)).toBeVisible();
5
+ await expect(page.locator("#sample-episode-visual [data-sample-caption]")).toContainText(/moon|robot|lilies|stones/i);
6
6
  });
7
7
 
8
8
  test("storyboard playback, character performance, caption timing, cuts, and nonblank cartoon frames are sourced", async ({
@@ -17,6 +17,7 @@ It uses:
17
17
  - A source-level studio panel with shot, dialogue, and render timeline tracks.
18
18
  - Asset library slot metadata for required characters and optional props.
19
19
  - Render pipeline metadata that agents can inspect before running full browser evidence.
20
+ - Template-local episode package scripts that write a deterministic `dist/episodes/moon-garden-001` review folder.
20
21
 
21
22
  Replace primitive characters with typed GLB assets by running:
22
23
 
@@ -44,3 +45,38 @@ Before closing build, route, asset, screenshot, render, or visual-quality gates,
44
45
  archive the matching `npm run build`, `assets validate-cartoon`, browser
45
46
  evidence, screenshot hashes, render outputs, and human or automated review
46
47
  artifacts.
48
+
49
+ ## Episode package scripts
50
+
51
+ The template includes the 1.1 Cartoon Studio command lane:
52
+
53
+ ```bash
54
+ npm run episode:plan
55
+ npm run episode:preview
56
+ npm run episode:render
57
+ npm run episode:package
58
+ npm run episode:review
59
+ npm run episode:verify
60
+ ```
61
+
62
+ The package is written to:
63
+
64
+ ```text
65
+ dist/episodes/moon-garden-001/
66
+ thumbnail.png
67
+ captions.vtt
68
+ captions.srt
69
+ metadata.json
70
+ route-proof.json
71
+ asset-provenance.json
72
+ render-manifest.json
73
+ visual-acceptance.json
74
+ review-package.md
75
+ ```
76
+
77
+ If no browser video encoder adapter is available, `episode:render` writes
78
+ `episode.png-sequence-fallback.json` and deterministic PNG frame placeholders
79
+ under `frames/`. That fallback proves the package/review workflow, but it is not
80
+ publish-ready cartoon video evidence. A release build must attach a real
81
+ WebM/MP4 encoder, use typed character/set assets, and pass human visual review
82
+ before claiming the episode is ready to publish.
@@ -0,0 +1,157 @@
1
+ {
2
+ "schema": "aura3d.assets/1.0",
3
+ "assetBasePath": "/aura-assets/",
4
+ "outputDir": "public/aura-assets",
5
+ "typegen": "src/aura-assets.ts",
6
+ "assets": [
7
+ {
8
+ "id": "luma",
9
+ "type": "model",
10
+ "format": "glb",
11
+ "source": "public/aura-assets/luma.humanoid-fixture.glb",
12
+ "outputPath": "public/aura-assets/luma.humanoid-fixture.glb",
13
+ "url": "/aura-assets/luma.humanoid-fixture.glb",
14
+ "hash": "sha256-dfb230fc1f942f259dd00281a1186953ad602fc5d69067ce63e24b2aa439736b",
15
+ "sizeBytes": 2160468,
16
+ "bounds": [1.1, 1.8, 0.8],
17
+ "boundsMetadata": {
18
+ "min": [-0.55, 0, -0.4],
19
+ "max": [0.55, 1.8, 0.4],
20
+ "size": [1.1, 1.8, 0.8],
21
+ "center": [0, 0.9, 0],
22
+ "maxDimension": 1.8,
23
+ "grounded": true
24
+ },
25
+ "materials": ["luma-body", "luma-face", "luma-accent"],
26
+ "materialMetadata": [
27
+ { "name": "luma-body", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
28
+ { "name": "luma-face", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
29
+ { "name": "luma-accent", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] }
30
+ ],
31
+ "animations": ["Idle", "Walking", "Wave", "Punch", "Jump"],
32
+ "animationMetadata": {
33
+ "clipCount": 5,
34
+ "clips": [
35
+ { "index": 0, "name": "Idle", "channelCount": 6, "samplerCount": 6, "targetPaths": ["rotation"], "targetNodes": ["Body", "Head", "UpperArm.L", "UpperArm.R"] },
36
+ { "index": 1, "name": "Walking", "channelCount": 8, "samplerCount": 8, "targetPaths": ["translation", "rotation"], "targetNodes": ["Body", "UpperLeg.L", "UpperLeg.R"] },
37
+ { "index": 2, "name": "Wave", "channelCount": 5, "samplerCount": 5, "targetPaths": ["rotation"], "targetNodes": ["Head", "UpperArm.R", "LowerArm.R"] },
38
+ { "index": 3, "name": "Punch", "channelCount": 5, "samplerCount": 5, "targetPaths": ["rotation"], "targetNodes": ["Body", "UpperArm.L", "LowerArm.L"] },
39
+ { "index": 4, "name": "Jump", "channelCount": 7, "samplerCount": 7, "targetPaths": ["translation", "rotation"], "targetNodes": ["Body", "UpperLeg.L", "UpperLeg.R"] }
40
+ ]
41
+ },
42
+ "humanoid": { "status": "candidate", "humanoid": true, "boneCount": 10 },
43
+ "skeleton": { "jointCount": 10, "skinnedMeshCount": 1 },
44
+ "morphTargets": { "targetCount": 0, "targetNames": [] },
45
+ "textures": [],
46
+ "dependencies": [],
47
+ "nodeNames": ["Luma", "Body", "Head", "mouth card", "UpperArm.L", "UpperArm.R", "UpperLeg.L", "UpperLeg.R"],
48
+ "provenance": {
49
+ "license": "CC0-1.0",
50
+ "author": "Aura3D",
51
+ "sourceFamily": "Aura3D curated starter pack",
52
+ "sourcePath": "public/aura-assets/luma.humanoid-fixture.glb",
53
+ "sourceUrl": "https://aura3d.auraone.ai/aura-assets/luma.humanoid-fixture.glb",
54
+ "attribution": "Bundled Aura3D starter rig for local cartoon-studio validation.",
55
+ "evidence": ["cartoon-character", "primitive mouth card", "rigged humanoid robot"]
56
+ },
57
+ "thumbnailUrl": "/aura-assets/luma.thumb.svg",
58
+ "warnings": []
59
+ },
60
+ {
61
+ "id": "miko",
62
+ "type": "model",
63
+ "format": "glb",
64
+ "source": "public/aura-assets/miko.047f5e5f.glb",
65
+ "outputPath": "public/aura-assets/miko.047f5e5f.glb",
66
+ "url": "/aura-assets/miko.047f5e5f.glb",
67
+ "hash": "sha256-047f5e5fb3bb6d378bd1df16ca6137f2a596c99b3a1b5690b4020c05aaf6f319",
68
+ "sizeBytes": 463988,
69
+ "bounds": [0.066, 0.026, 0.017],
70
+ "boundsMetadata": {
71
+ "min": [-0.033, -0.013, -0.009],
72
+ "max": [0.033, 0.013, 0.008],
73
+ "size": [0.066, 0.026, 0.017],
74
+ "center": [0, 0, 0],
75
+ "maxDimension": 0.066,
76
+ "grounded": true
77
+ },
78
+ "materials": ["Grey", "Main", "Black"],
79
+ "materialMetadata": [
80
+ { "name": "Grey", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
81
+ { "name": "Main", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
82
+ { "name": "Black", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] }
83
+ ],
84
+ "animations": ["Dance", "Death", "Idle", "Jump", "Punch", "Running", "Walking", "Wave"],
85
+ "animationMetadata": {
86
+ "clipCount": 8,
87
+ "clips": [
88
+ { "index": 0, "name": "Dance", "channelCount": 12, "samplerCount": 12, "targetPaths": ["weights", "translation", "rotation"], "targetNodes": ["Head", "Body", "UpperArm.L", "UpperArm.R"] },
89
+ { "index": 1, "name": "Death", "channelCount": 18, "samplerCount": 18, "targetPaths": ["weights", "translation", "rotation"], "targetNodes": ["Head", "Body", "UpperArm.L", "UpperArm.R"] },
90
+ { "index": 2, "name": "Idle", "channelCount": 7, "samplerCount": 7, "targetPaths": ["weights", "translation", "rotation"], "targetNodes": ["Head", "Body"] },
91
+ { "index": 3, "name": "Jump", "channelCount": 10, "samplerCount": 10, "targetPaths": ["translation", "rotation"], "targetNodes": ["Body", "UpperLeg.L", "UpperLeg.R"] },
92
+ { "index": 4, "name": "Punch", "channelCount": 8, "samplerCount": 8, "targetPaths": ["rotation"], "targetNodes": ["Body", "UpperArm.L", "LowerArm.L"] },
93
+ { "index": 5, "name": "Running", "channelCount": 10, "samplerCount": 10, "targetPaths": ["translation", "rotation"], "targetNodes": ["Body", "UpperLeg.L", "UpperLeg.R"] },
94
+ { "index": 6, "name": "Walking", "channelCount": 10, "samplerCount": 10, "targetPaths": ["translation", "rotation"], "targetNodes": ["Body", "UpperLeg.L", "UpperLeg.R"] },
95
+ { "index": 7, "name": "Wave", "channelCount": 8, "samplerCount": 8, "targetPaths": ["rotation"], "targetNodes": ["Head", "UpperArm.R", "LowerArm.R"] }
96
+ ]
97
+ },
98
+ "humanoid": { "status": "candidate", "humanoid": true, "boneCount": 10 },
99
+ "skeleton": { "jointCount": 10, "skinnedMeshCount": 1 },
100
+ "morphTargets": { "targetCount": 1, "targetNames": ["mouthSmile"] },
101
+ "textures": [],
102
+ "dependencies": [],
103
+ "nodeNames": ["Miko", "Head", "Body", "mouth card", "UpperArm.L", "UpperArm.R", "UpperLeg.L", "UpperLeg.R"],
104
+ "provenance": {
105
+ "license": "CC0-1.0",
106
+ "author": "Aura3D",
107
+ "sourceFamily": "Aura3D curated starter pack",
108
+ "sourcePath": "public/aura-assets/miko.047f5e5f.glb",
109
+ "sourceUrl": "https://aura3d.auraone.ai/aura-assets/miko.047f5e5f.glb",
110
+ "attribution": "Bundled Aura3D starter rig for local cartoon-studio validation.",
111
+ "evidence": ["cartoon-character", "blendshape mouth", "rigged humanoid robot"]
112
+ },
113
+ "thumbnailUrl": "/aura-assets/miko.thumb.svg",
114
+ "warnings": []
115
+ },
116
+ {
117
+ "id": "moonGarden",
118
+ "type": "model",
119
+ "format": "gltf",
120
+ "source": "public/aura-assets/moonGarden.gltf",
121
+ "outputPath": "public/aura-assets/moonGarden.gltf",
122
+ "url": "/aura-assets/moonGarden.gltf",
123
+ "hash": "sha256-85a288d6d434cc5c56ac154c3e996c2ad7612791622fc20a339fb647a6d426bd",
124
+ "sizeBytes": 3744,
125
+ "bounds": [3.2, 0.6, 1.2],
126
+ "boundsMetadata": {
127
+ "min": [-1.6, 0, -0.6],
128
+ "max": [1.6, 0.6, 0.6],
129
+ "size": [3.2, 0.6, 1.2],
130
+ "center": [0, 0.3, 0],
131
+ "maxDimension": 3.2,
132
+ "grounded": true
133
+ },
134
+ "materials": ["soft blue moon path", "warm glow stone", "distant teal skyline"],
135
+ "materialMetadata": [
136
+ { "name": "soft blue moon path", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
137
+ { "name": "warm glow stone", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] },
138
+ { "name": "distant teal skyline", "visible": true, "readable": true, "opacity": 1, "alphaMode": "OPAQUE", "reasons": [] }
139
+ ],
140
+ "animations": [],
141
+ "textures": [],
142
+ "dependencies": [],
143
+ "nodeNames": ["Moon Garden starter set anchor", "moon garden floor anchor", "moon garden glow stone anchor", "moon garden skyline anchor", "walkable garden set"],
144
+ "provenance": {
145
+ "license": "MIT",
146
+ "author": "Aura3D",
147
+ "sourceFamily": "Aura3D curated starter pack",
148
+ "sourcePath": "public/aura-assets/moonGarden.gltf",
149
+ "sourceUrl": "https://aura3d.auraone.ai/aura-assets/moonGarden.gltf",
150
+ "attribution": "Bundled Aura3D Moon Garden starter set for local cartoon-studio validation.",
151
+ "evidence": ["cartoon-set", "moon garden", "walkable set", "framing ready"]
152
+ },
153
+ "thumbnailUrl": "/aura-assets/moonGarden.thumb.svg",
154
+ "warnings": []
155
+ }
156
+ ]
157
+ }