cozyclay 1.1.0 → 1.3.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 (138) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +91 -25
  3. package/THIRD_PARTY_NOTICES.md +68 -1
  4. package/bin/cozyclay.mjs +71 -8
  5. package/dist/CNAME +1 -0
  6. package/dist/ai-camera-control/index.html +406 -0
  7. package/dist/app/index.html +57 -0
  8. package/dist/assets/app-B3U5aut1.js +4811 -0
  9. package/dist/assets/app-BrRF0wso.css +1 -0
  10. package/dist/assets/vision_bundle-jFkh-fIS.js +41 -0
  11. package/dist/favicon.ico +0 -0
  12. package/dist/fonts/InstrumentSerif-OFL.txt +93 -0
  13. package/dist/fonts/Inter-OFL.txt +92 -0
  14. package/dist/fonts/README.md +15 -0
  15. package/dist/icons/apple-touch-icon.png +0 -0
  16. package/dist/icons/icon-192.png +0 -0
  17. package/dist/icons/icon-32.png +0 -0
  18. package/dist/icons/icon-512.png +0 -0
  19. package/dist/icons/icon-maskable-512.png +0 -0
  20. package/dist/index.html +450 -5
  21. package/dist/manifest.webmanifest +42 -0
  22. package/dist/media/cozyclay-demo-poster.jpg +0 -0
  23. package/dist/media/cozyclay-logo.png +0 -0
  24. package/dist/robots.txt +4 -0
  25. package/dist/sitemap.xml +15 -0
  26. package/dist/sw.js +127 -0
  27. package/mcp/LIVE-PROTOCOL.md +63 -0
  28. package/mcp/README.md +142 -0
  29. package/mcp/ardy-prompts.mjs +170 -0
  30. package/mcp/live-hub.mjs +105 -0
  31. package/mcp/package.json +24 -0
  32. package/mcp/server.mjs +1394 -0
  33. package/package.json +122 -78
  34. package/src/App.jsx +4235 -1047
  35. package/src/ardy/client.js +5 -4
  36. package/src/ardy/cskel27.js +7 -2
  37. package/src/ardy/ik.js +25 -15
  38. package/src/ardy/mp4-duration.js +102 -0
  39. package/src/ardy/npz.js +64 -3
  40. package/src/ardy/playback.js +31 -1
  41. package/src/ardy/prompt-clips.js +7 -2
  42. package/src/ardy/retime.js +211 -0
  43. package/src/ardy/timeline-coordinates.js +24 -0
  44. package/src/ardy/timeline.jsx +650 -70
  45. package/src/ardy/to-cskel27.js +34 -12
  46. package/src/ardy/trim.js +33 -0
  47. package/src/ardy/waypoints.js +14 -9
  48. package/src/asset-pane.jsx +36 -0
  49. package/src/camera-block.js +60 -0
  50. package/src/camera-follow.js +49 -10
  51. package/src/camera-rail-schedule.js +176 -0
  52. package/src/controls.jsx +16 -2
  53. package/src/cuts.js +184 -0
  54. package/src/dualview.jsx +14 -8
  55. package/src/generation/client.js +56 -0
  56. package/src/generation/session.js +47 -0
  57. package/src/generation/shot-spec.js +40 -0
  58. package/src/generation/use-generation.js +55 -0
  59. package/src/hierarchy-model.js +104 -30
  60. package/src/hierarchy-panel.jsx +306 -26
  61. package/src/live-control.js +122 -0
  62. package/src/locale-toggle.jsx +18 -0
  63. package/src/locale.js +34 -0
  64. package/src/main.jsx +5 -0
  65. package/src/matte-editor.js +543 -0
  66. package/src/matte.js +503 -0
  67. package/src/multimodel-ingest.js +344 -0
  68. package/src/object-catalog.jsx +32 -3
  69. package/src/object-gizmo.jsx +43 -15
  70. package/src/planview.jsx +208 -89
  71. package/src/pose-extract/browser.js +42 -0
  72. package/src/pose-extract/detector.js +75 -0
  73. package/src/pose-extract/fit.js +194 -0
  74. package/src/pose-extract/index.js +56 -0
  75. package/src/pose-extract/keyframes.js +74 -0
  76. package/src/pose-extract/landmarks.js +162 -0
  77. package/src/pose-extract/take.js +87 -0
  78. package/src/pose-extract/video-frames.js +91 -0
  79. package/src/pose-thumbs.js +152 -0
  80. package/src/poses.js +114 -0
  81. package/src/posestudio.jsx +434 -22
  82. package/src/project-browser.jsx +135 -0
  83. package/src/project.js +289 -0
  84. package/src/props.jsx +69 -3
  85. package/src/pwa.js +42 -0
  86. package/src/result-modal.jsx +124 -0
  87. package/src/room.jsx +14 -35
  88. package/src/scene-asset-cache.js +125 -0
  89. package/src/scene-assets.js +288 -0
  90. package/src/scene-objects.js +245 -7
  91. package/src/scenes.js +404 -0
  92. package/src/shot-authoring.js +246 -77
  93. package/src/shot.js +8 -4
  94. package/src/styles.css +2151 -183
  95. package/src/ui.jsx +54 -5
  96. package/tools/ardy/BRIDGE.md +73 -6
  97. package/tools/ardy/README.md +64 -5
  98. package/tools/ardy/bridge.mjs +146 -390
  99. package/tools/ardy/bvh-cskel27.mjs +1209 -0
  100. package/tools/ardy/cclay_constrained_generate.py +561 -0
  101. package/tools/ardy/cclay_motion_edit.py +74 -9
  102. package/tools/ardy/cclay_sequence_generate.py +117 -7
  103. package/tools/ardy/cclay_worker.py +304 -0
  104. package/tools/ardy/extract.mjs +367 -0
  105. package/tools/ardy/footage.mjs +462 -0
  106. package/tools/ardy/merge-text-encoder.py +160 -0
  107. package/tools/ardy/npz.mjs +74 -9
  108. package/tools/ardy/run-local.mjs +233 -0
  109. package/tools/ardy/run-on-box.sh +25 -0
  110. package/tools/ardy/run-sequence-on-box.sh +15 -0
  111. package/tools/ardy/runners/index.mjs +23 -0
  112. package/tools/ardy/runners/local.mjs +452 -0
  113. package/tools/ardy/runners/proc.mjs +125 -0
  114. package/tools/ardy/runners/remote.mjs +252 -0
  115. package/tools/ardy/setup-local.mjs +189 -0
  116. package/tools/ardy/setup-text-encoder-on-box.sh +93 -0
  117. package/tools/ardy/setup-text-encoder.py +296 -0
  118. package/tools/generation/README.md +29 -0
  119. package/tools/generation/bridge.mjs +149 -0
  120. package/tools/generation/job-store.mjs +51 -0
  121. package/tools/generation/providers/kling.mjs +76 -0
  122. package/tools/generation/providers/runway.mjs +101 -0
  123. package/tools/generation/providers/seedance.mjs +87 -0
  124. package/tools/generation/providers/shared.mjs +49 -0
  125. package/tools/generation/providers/veo.mjs +84 -0
  126. package/tools/metrics/archive-traffic.mjs +138 -0
  127. package/dist/assets/index-BW_S1YRy.js +0 -4395
  128. package/dist/assets/index-nRmmJgap.css +0 -1
  129. package/tools/ardy/__pycache__/cclay_sequence_generate.cpython-313.pyc +0 -0
  130. package/tools/ardy/out/gen-1786443326924-c6019e-generated.npz +0 -0
  131. package/tools/ardy/out/gen-1786443609325-0053db-generated.npz +0 -0
  132. package/tools/ardy/out/gen-1786443835628-749ed1-generated.npz +0 -0
  133. package/tools/ardy/out/gen-1786462605247-03cb19-generated.npz +0 -0
  134. package/tools/qa-browser.mjs +0 -84
  135. package/tools/qa-crop3.mjs +0 -22
  136. package/tools/qa-playview.mjs +0 -49
  137. package/tools/qa-screenshot.mjs +0 -24
  138. package/tools/qa-visual.mjs +0 -51
package/CHANGELOG.md ADDED
@@ -0,0 +1,85 @@
1
+ # Changelog
2
+
3
+ ## 1.3.0
4
+
5
+ The release where the studio stops being something only a person can drive.
6
+
7
+ ### Direct it with an AI
8
+
9
+ CozyClay now ships an [MCP](https://modelcontextprotocol.io) server. Point Claude, Cursor, or any
10
+ MCP client at it and ask for a shot in plain language — it places the cast, frames "a low wide
11
+ profile", generates multi-phase motion, and **the viewport moves while you watch**.
12
+
13
+ ```json
14
+ { "mcpServers": { "cozyclay": { "command": "npx", "args": ["-y", "cozyclay", "mcp"] } } }
15
+ ```
16
+
17
+ It computes nothing of its own. Every answer comes from the modules the studio already renders
18
+ with — `shot.js` for film vocabulary, `scenes.js` for the stage, `camera-move.js` for moves — so
19
+ the server and the UI cannot disagree about what a 35 mm medium shot is.
20
+
21
+ - **Live or headless.** With a studio tab open, tool calls drive the real viewport over a local
22
+ socket. With no tab, the same tools run headless: block scenes, derive framing, render prompts,
23
+ and write `.cclayproject` files the studio opens.
24
+ - **Motion from plain beats.** `generate_motion` takes ordinary sentences, rewrites them into the
25
+ shape ARDY was trained to read, splits compound beats, drops language a body cannot perform, and
26
+ lands each phase as a Prompt Block on the timeline.
27
+ - **21 tools**, all documented in [`mcp/README.md`](mcp/README.md).
28
+
29
+ ### Cut a photograph out and stand it up
30
+
31
+ Drop an image on Props — or straight onto the shot — and it becomes a card you can place, turn and
32
+ block against. The background editor lives in the card's own inspector: paint or erase the
33
+ selection, zoom and pan with the wheel, and the picture sits on a stage rather than being framed
34
+ by one. Assets are stored once by content hash, so the same picture imported twice costs one copy.
35
+
36
+ ### An open stage
37
+
38
+ The two-walled room corner is gone. The set is a 500 m open deck — far enough that no ordinary
39
+ blocking meets its edge — with a two-tier grid (quiet 1 m cells, assertive 10 m lines) and a
40
+ distance falloff that dissolves the floor into the background instead of ending at a horizon.
41
+ Movement clamps moved from ±11 m to ±240 m, so a run or a chase finally has room.
42
+
43
+ ### Group props and move them as one
44
+
45
+ Scene objects now carry a parent. Build a rocket from ten primitives, group them, and the whole
46
+ thing drags as one body — through the gizmo, the inspector and the MCP tools alike. Deleting a
47
+ parent promotes its children rather than taking them with it.
48
+
49
+ ### Everything else
50
+
51
+ - **Gizmo** — the cast rides the same gizmo as scene objects, with rotate and scale; an XZ pad for
52
+ free ground drags; pick targets balanced so the pad no longer swallows every press.
53
+ - **Mocap** — a video capture panel, takes assigned to cast members, and take trimming.
54
+ - **Timeline** — authoring runs on a 24 fps production clock while ARDY is still spoken to at
55
+ 20 fps, and exports record at true motion speed.
56
+ - **Multi-character** — an unbounded cast with per-character motion layers.
57
+
58
+ ### Fixes
59
+
60
+ - Props reported `1x1x1` regardless of how they were built: scale never crossed the live protocol,
61
+ and the server reset whatever did arrive. Sizes are now real, and per-axis scale is exposed.
62
+ - A 6 m ceiling survived the walls it belonged to, silently decapitating anything tall.
63
+ - Generating four Prompt Blocks produced one. IK keys from a discarded take made a fresh run look
64
+ like a local edit, and that path ships no schedule. Replacing a take now clears the corrections
65
+ authored against it.
66
+ - A stale service worker served yesterday's bundle to the dev server, so edits appeared to do
67
+ nothing. Dev now serves a self-destructing worker.
68
+ - Prompt blocks are capped at 4 s everywhere, not just in the UI — longer beats chain instead of
69
+ being authored into something the timeline would refuse.
70
+
71
+ ### Packaging
72
+
73
+ - `mcp/` ships with the package, so `npx cozyclay mcp` works without a clone.
74
+ - `exports` makes `cozyclay/src/*` a public contract instead of an accident.
75
+ - `three` is declared as an optional peer: the studio bundles its own copy, but anything importing
76
+ `cozyclay/src/*` needs it, and now npm says so.
77
+
78
+ ## 1.2.0
79
+
80
+ - `npx cozyclay` opens the studio again.
81
+ - Stopped shipping 26 MB of scratch files.
82
+
83
+ ## 0.1.0
84
+
85
+ First public release.
package/README.md CHANGED
@@ -1,23 +1,57 @@
1
- # CozyClay
1
+ <p align="center">
2
+ <img src="docs/images/cozyclay-logo.png" alt="CozyClay" width="340">
3
+ </p>
4
+
5
+ <p align="center">
6
+ <em>Block a scene, pose the cast, cut the camera — in a browser tab.</em>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="LICENSE"><img alt="License: GPL-3.0" src="https://img.shields.io/badge/license-GPL--3.0-blue"></a>
11
+ <a href="https://www.npmjs.com/package/cozyclay"><img alt="npm" src="https://img.shields.io/npm/v/cozyclay"></a>
12
+ <img alt="Node 22+" src="https://img.shields.io/badge/node-22%2B-brightgreen">
13
+ <a href="https://github.com/HaD0Yun/CozyClay/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/HaD0Yun/CozyClay?style=flat"></a>
14
+ </p>
15
+
16
+ <p align="center">
17
+ <a href="https://cozyclay.org/">Demo reel</a> ·
18
+ <a href="#quick-start">Quick start</a> ·
19
+ <a href="#what-you-can-do">Features</a> ·
20
+ <a href="#ai-control-mcp">AI control</a> ·
21
+ <a href="#controls">Controls</a> ·
22
+ <a href="https://github.com/HaD0Yun/CozyClay/issues">Issues</a>
23
+ </p>
24
+
25
+ ---
26
+
27
+ CozyClay is a browser-based 3D staging studio built with Three.js and React Three Fiber. Block a scene, pose characters, sequence motion prompts on a timeline, and preview generated motion — all in one local workspace.
2
28
 
3
- CozyClay is a browser-based 3D staging studio built with Three.js and React Three Fiber. Block a scene, pose characters, sequence motion prompts on a timeline, and preview generated motion — in one local workspace that handles like the Unity Editor.
4
-
5
- **[Open the live demo](https://had0yun.github.io/CozyClay/)** — the studio itself, running in your browser. Nothing to install. It comes seeded with a pre-generated motion clip so you can scrub the timeline, drive the cameras and draw a dolly rail straight away; generating new motion needs a local ARDY machine, so that part is off.
29
+ ```bash
30
+ npx cozyclay
31
+ ```
6
32
 
7
- ![CozyClay browser-based 3D staging studio](docs/images/cozyclay-studio.png)
33
+ That is the whole install. **[cozyclay.org](https://cozyclay.org/)** has the demo reel and a walkthrough of what the studio does; to use it, run it on your own machine. It ships seeded with a pre-generated motion clip, so you can scrub the timeline, drive the cameras and draw a dolly rail straight away — generating *new* motion needs a local ARDY machine, so that part stays off until you point it at one.
8
34
 
9
35
  ## Demo
10
36
 
11
- ![CozyClay motion, staging, and camera workflow](docs/images/cozyclay-demo.gif)
37
+ https://github.com/user-attachments/assets/1d0113e5-6922-443d-affc-1bdabc666247
12
38
 
13
- CozyClay can connect to [NVIDIA ARDY](https://github.com/nv-tlabs/ardy) for motion generation. ARDY is a separate third-party project owned and maintained by NVIDIA; it is not included in this repository, and CozyClay is not affiliated with or endorsed by NVIDIA.
39
+ ## What you can do
40
+
41
+ | | |
42
+ | --- | --- |
43
+ | **Stage a scene** | Create primitives and set pieces, then move, rotate and scale them with a W/E/R gizmo. Grid snapping is a preference, not a law — hold `Ctrl` mid-drag to invert it. A bird's-eye plan view drives 2D root waypoints for character paths. |
44
+ | **Fly the camera** | Right-drag flies (WASD walks, Q/E cranes), middle-drag pans, Alt+drag orbits the selection, click selects, `F` frames — the muscle memory you already have from a 3D editor. |
45
+ | **Undo anything** | Every scene mutation goes through one history store: a drag, a scrub, an inspector edit is exactly one undo entry. `Esc` cancels an in-flight drag and restores the pre-drag transform. |
46
+ | **Generate motion** | Pose characters and export poses, sequence multi-phase motion as Prompt Blocks on a resizable timeline, send them to ARDY, then play the result back with sparse IK correction where the generated motion needs fixing. |
47
+ | **Direct it with an AI** | Connect Claude — or any MCP client — and ask for a shot in plain language. It places the cast, frames “a low wide profile”, generates multi-phase motion, and the viewport moves in front of you. See [AI control](#ai-control-mcp). |
14
48
 
15
49
  ## Requirements
16
50
 
17
51
  - Node.js 22 or newer
18
52
  - npm, or bun
19
53
  - A Chromium-based browser
20
- - Optional: an SSH-accessible NVIDIA machine running ARDY, for motion generation
54
+ - *Optional:* an SSH-accessible NVIDIA machine running ARDY, for motion generation
21
55
 
22
56
  ## Quick start
23
57
 
@@ -27,17 +61,42 @@ npx cozyclay
27
61
  bunx cozyclay
28
62
  ```
29
63
 
30
- That downloads the built studio and opens it at `http://127.0.0.1:5180`. There is
31
- nothing to compile and no dependency tree to install. Useful flags:
32
- `--port 5200`, `--no-open`, `--no-ardy`.
64
+ That downloads the built studio and opens it at `http://127.0.0.1:5180`. Nothing to compile, no dependency tree to install. Useful flags: `--port 5200`, `--no-open`, `--no-ardy`.
33
65
 
34
- Motion generation is off until you point it at a machine that can run it:
66
+ Motion generation stays off until you point it at a machine that can run it:
35
67
 
36
68
  ```bash
37
69
  CCLAY_ARDY_HOST=user@your-gpu-box npx cozyclay
38
70
  ```
39
71
 
40
- Everything else, staging through camera work and playback, runs without it.
72
+ Everything else staging through camera work and playback runs without it.
73
+
74
+ ## AI control (MCP)
75
+
76
+ The studio ships an [MCP](https://modelcontextprotocol.io) server, so an AI assistant can drive it — the same scene, the same viewport, live:
77
+
78
+ > “Put a detective and a courier in an alley, give me a low wide profile shot,
79
+ > then make her stand up from the chair, sprint, and trip.”
80
+
81
+ ```json
82
+ {
83
+ "mcpServers": {
84
+ "cozyclay": {
85
+ "command": "npx",
86
+ "args": ["-y", "cozyclay", "mcp"]
87
+ }
88
+ }
89
+ }
90
+ ```
91
+
92
+ Drop that into `claude_desktop_config.json` (or any MCP client config) and restart the client. The
93
+ first run prints one `npm install` line: the MCP SDK is a 95-package tree, and opening the studio
94
+ should never wait on it, so those dependencies are fetched only when you actually want the server.
95
+
96
+ - **Editor open?** Tool calls move the visible viewport — camera, cast, set, generated motion, prompt blocks on the timeline.
97
+ - **No editor?** The same tools run headless: block scenes, derive film vocabulary (“wide shot · right profile · knee level · 24mm”), render AI video prompts, and write `.cclayproject` files the studio opens.
98
+
99
+ Tools, transports and the live-control protocol are documented in [`mcp/README.md`](mcp/README.md).
41
100
 
42
101
  ### From a clone
43
102
 
@@ -48,19 +107,20 @@ npm install
48
107
  npm run dev
49
108
  ```
50
109
 
51
- Open `http://127.0.0.1:5180`. `npm run dev` starts the studio together with its local ARDY bridge; `npm run dev:ui` starts the browser UI alone, without Block Generation.
52
-
53
- The bridge listens on loopback only. The environment variables that point it at a remote ARDY machine are documented in `tools/ardy/BRIDGE.md`.
110
+ Open `http://127.0.0.1:5180`. `npm run dev` starts the studio together with its local ARDY bridge; `npm run dev:ui` starts the browser UI alone, without Block Generation. The bridge listens on loopback only; the environment variables that point it at a remote ARDY machine are documented in [`tools/ardy/BRIDGE.md`](tools/ardy/BRIDGE.md).
54
111
 
55
- ## What you can do
112
+ <details>
113
+ <summary><b>Token-free ARDY text encoder</b> — skip the Hugging Face gate</summary>
56
114
 
57
- **Stage a scene.** Create primitives and set pieces, then move, rotate, and scale them with a W/E/R gizmo. Grid snapping is a preference, not a law hold `Ctrl` during a drag to invert it. A bird's-eye plan view drives 2D root waypoints for character paths.
115
+ ARDY's text encoder normally requires a Hugging Face account, gated-model approval, and an access token on the ARDY machine. CozyClay ships a token-free alternativeone command provisions the same encoder stack from public repositories, pinned by commit and SHA-256:
58
116
 
59
- **Edit like Unity.** Right-drag flies the camera (WASD walks, Q/E cranes), middle-drag pans, Alt+drag orbits the selection, left click selects, `F` frames. The full rule set, its source in Unity's manual, and every deliberate divergence are recorded in `docs/unity-reference.md`.
117
+ ```bash
118
+ CCLAY_ARDY_HOST=user@your-gpu-box tools/ardy/setup-text-encoder-on-box.sh
119
+ ```
60
120
 
61
- **Undo anything.** Every scene mutation goes through a single history store: one interaction a drag, a scrub, an inspector edit is exactly one undo entry. `Esc` cancels an in-flight drag and restores the pre-drag transform.
121
+ See [`tools/ardy/README.md`](tools/ardy/README.md) for details. This workflow is built with Meta Llama 3; the encoder's base weights are licensed under the Meta Llama 3 Community License.
62
122
 
63
- **Generate motion.** Pose characters and export poses, sequence multi-phase motion as Prompt Blocks on a resizable timeline, send them to ARDY, then play the result back with sparse IK correction where the generated motion needs fixing.
123
+ </details>
64
124
 
65
125
  ## Controls
66
126
 
@@ -92,6 +152,8 @@ The bridge listens on loopback only. The environment variables that point it at
92
152
  | `npm run test:theme` / `test:appearance` / `test:layout` | UI theme, appearance, layout |
93
153
  | `npm run test:lifecycle` | Dev-server process lifecycle |
94
154
  | `npm run test:ardy` | ARDY conversion, playback, and IK pipeline |
155
+ | `cd mcp && npm run verify` | MCP server over real stdio — all 420 framing combinations |
156
+ | `cd mcp && npm run verify:live` | Live-control protocol against a fake editor |
95
157
  | `npm run build` | Production build |
96
158
 
97
159
  Ad-hoc browser QA, while a dev server is available:
@@ -100,10 +162,14 @@ Ad-hoc browser QA, while a dev server is available:
100
162
  npm run qa:browser -- <qa-script>
101
163
  ```
102
164
 
103
- ## Repository hygiene
165
+ ## Contributing
166
+
167
+ Found something broken, or want a feature? [Open an issue](https://github.com/HaD0Yun/CozyClay/issues) — bug reports with a repro are the most useful thing you can send.
104
168
 
105
- Generated motion archives, QA output, build output, logs, and local runtime artifacts are not source files and must not be committed. In particular, keep `tools/ardy/out/`, `artifacts/`, `dist/`, `.gjc/`, and `.npz` files local.
169
+ **Repository hygiene.** Generated motion archives, QA output, build output, logs and local runtime artifacts are not source files and must not be committed. Keep `tools/ardy/out/`, `artifacts/`, `dist/`, `.gjc/` and `.npz` files local.
106
170
 
107
- ## License
171
+ ## License & credits
108
172
 
109
- GNU General Public License v3.0 or later — see `LICENSE`. Third-party projects retain their own licenses and copyright; see `THIRD_PARTY_NOTICES.md`.
173
+ GNU General Public License v3.0 or later — see [`LICENSE`](LICENSE). Third-party projects retain their own licenses and copyright; see [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md).
174
+
175
+ CozyClay can connect to [NVIDIA ARDY](https://github.com/nv-tlabs/ardy) for motion generation. ARDY is a separate third-party project owned and maintained by NVIDIA; it is not included in this repository, and CozyClay is not affiliated with or endorsed by NVIDIA.
@@ -24,6 +24,73 @@ ARDY is not bundled with CozyClay. Users must obtain, install, and operate ARDY
24
24
 
25
25
  ARDY model checkpoints and other model assets may be governed by separate terms, including the NVIDIA Open Model License identified by the ARDY project. Users are responsible for reviewing and complying with those terms before downloading or using the models.
26
26
 
27
+ ## Meta Llama 3
28
+
29
+ ARDY's text encoder is based on Meta Llama 3 (`Meta-Llama-3-8B-Instruct`).
30
+ CozyClay does not bundle or redistribute the model weights; the optional
31
+ `tools/ardy/setup-text-encoder.py` script downloads them directly from a
32
+ public repository to the user's own machine for local use, together with the
33
+ model's LICENSE and USE_POLICY files.
34
+
35
+ Built with Meta Llama 3.
36
+
37
+ - Copyright © Meta Platforms, Inc. All Rights Reserved.
38
+ - License: Meta Llama 3 Community License
39
+ - License text: https://www.llama.com/llama3/license/
40
+ - Acceptable Use Policy: https://www.llama.com/llama3/use-policy/
41
+
42
+ Meta Llama 3 is licensed under the Meta Llama 3 Community License,
43
+ Copyright © Meta Platforms, Inc. All Rights Reserved.
44
+
45
+ ## LLM2Vec
46
+
47
+ ARDY's text encoder applies the LLM2Vec adapters from McGill NLP
48
+ (`LLM2Vec-Meta-Llama-3-8B-Instruct-mntp` and `-mntp-supervised`). Like the
49
+ base weights, they are downloaded by the setup script for local use, not
50
+ bundled.
51
+
52
+ - Copyright (c) 2024 McGill NLP
53
+ - License: MIT (the adapters are derived from Meta Llama 3; the Meta Llama 3
54
+ Community License applies to that underlying model)
55
+ - Source: https://github.com/McGill-NLP/llm2vec
56
+ - License text: https://github.com/McGill-NLP/llm2vec/blob/main/LICENSE
57
+
58
+ ## Fonts
59
+
60
+ CozyClay bundles subsets of two typefaces. Both are licensed under the SIL Open
61
+ Font License 1.1, which allows them to be redistributed with software as long as
62
+ the copyright notice and the licence travel with the files. The licence texts are
63
+ in `public/fonts/` next to the fonts themselves.
64
+
65
+ ### Inter
66
+
67
+ - Copyright (c) 2016 The Inter Project Authors
68
+ - License: SIL Open Font License 1.1
69
+ - Source: https://github.com/rsms/inter
70
+ - License text: `public/fonts/Inter-OFL.txt`
71
+
72
+ ### Instrument Serif
73
+
74
+ - Copyright 2022 The Instrument Serif Project Authors
75
+ - License: SIL Open Font License 1.1
76
+ - Source: https://github.com/Instrument/instrument-serif
77
+ - License text: `public/fonts/InstrumentSerif-OFL.txt`
78
+
79
+ ## Character models
80
+
81
+ The rigs in `public/models/` are Mixamo characters from Adobe. Adobe permits
82
+ their use in projects but not the distribution of the raw character files, which
83
+ is what shipping them in this repository, the npm package and the hosted site
84
+ amounts to. They are also outside the scope of this repository's GPL-3.0 grant:
85
+ nothing here relicenses them, and a fork does not acquire the right to
86
+ redistribute them.
87
+
88
+ They are being replaced with a CC0 rig. Until that lands, treat these two files
89
+ as third-party content that this licence does not cover.
90
+
91
+ - `x-bot-tpose.fbx`, `y-bot-tpose.fbx` — Adobe Mixamo
92
+ - Terms: https://www.adobe.com/legal/terms.html
93
+
27
94
  ## CozyClay license scope
28
95
 
29
- The CozyClay source code in this repository is licensed under GPL-3.0-or-later. That license does not replace or relicense Three.js, ARDY, ARDY model checkpoints, or any other third-party component.
96
+ The CozyClay source code in this repository is licensed under GPL-3.0-or-later. That license does not replace or relicense Three.js, ARDY, ARDY model checkpoints, the bundled fonts, the character rigs, or any other third-party component.
package/bin/cozyclay.mjs CHANGED
@@ -79,6 +79,7 @@ const STAR_AFTER_MS = Number(process.env.COZYCLAY_STAR_AFTER_MS ?? 60_000);
79
79
  const HELP = `cozyclay - browser-based 3D staging studio
80
80
 
81
81
  npx cozyclay start the studio and open it
82
+ npx cozyclay mcp run the MCP server (for Claude, Cursor, any MCP client)
82
83
  npx cozyclay --port 5200 serve on another port
83
84
  npx cozyclay --no-ardy skip the optional motion-generation sidecar
84
85
  npx cozyclay --no-open do not open a browser
@@ -189,7 +190,50 @@ function openBrowser(url) {
189
190
  child.unref();
190
191
  }
191
192
 
192
- const opts = parseArgs(process.argv.slice(2));
193
+ /**
194
+ * `cozyclay mcp` hands over to the MCP server.
195
+ *
196
+ * Its dependencies are NOT the launcher's: the studio path stays dependency
197
+ * free on purpose, and the MCP SDK is a 95-package tree nobody who only wants
198
+ * a viewport should download. So the server ships with the package, its deps
199
+ * are installed on demand, and a missing one produces an exact instruction
200
+ * rather than a stack trace.
201
+ */
202
+ async function runMcp(rest) {
203
+ const server = join(PKG_ROOT, "mcp", "server.mjs");
204
+ if (!existsSync(server)) {
205
+ console.error("cozyclay: this build does not include the MCP server.");
206
+ process.exit(1);
207
+ }
208
+ // The deps must land in the PACKAGE root, not in mcp/: server.mjs imports
209
+ // ../src/*.js, and those files resolve `three` from cozyclay/ itself.
210
+ try {
211
+ await import("@modelcontextprotocol/sdk/server/mcp.js");
212
+ await import("three");
213
+ } catch {
214
+ console.error(
215
+ [
216
+ "cozyclay: the MCP server needs four packages the studio does not.",
217
+ "",
218
+ ` npm install --prefix ${JSON.stringify(PKG_ROOT)} \\`,
219
+ " @modelcontextprotocol/sdk ws zod three",
220
+ "",
221
+ "Then run `npx cozyclay mcp` again. They are kept out of the default",
222
+ "install so opening the studio never waits on a 95-package tree.",
223
+ ].join("\n"),
224
+ );
225
+ process.exit(1);
226
+ }
227
+ const child = spawn(process.execPath, [server, ...rest], { stdio: "inherit" });
228
+ child.on("exit", (code, signal) => process.exit(signal ? 1 : (code ?? 0)));
229
+ }
230
+
231
+ const argv = process.argv.slice(2);
232
+ if (argv[0] === "mcp") {
233
+ await runMcp(argv.slice(1));
234
+ } else {
235
+
236
+ const opts = parseArgs(argv);
193
237
  if (opts.help) {
194
238
  console.log(HELP);
195
239
  process.exit(0);
@@ -199,8 +243,8 @@ if (opts.version) {
199
243
  console.log(pkg.version);
200
244
  process.exit(0);
201
245
  }
202
- if (!existsSync(join(DIST, "index.html"))) {
203
- console.error("cozyclay: this package is missing its build (dist/index.html).");
246
+ if (!existsSync(join(DIST, "app", "index.html"))) {
247
+ console.error("cozyclay: this package is missing its build (dist/app/index.html).");
204
248
  console.error("cozyclay: from a clone, run `npm install && npm run build` first.");
205
249
  process.exit(1);
206
250
  }
@@ -219,14 +263,28 @@ if (opts.ardy && ardyHost && existsSync(BRIDGE)) {
219
263
 
220
264
  const server = createServer((req, res) => {
221
265
  const url = new URL(req.url ?? "/", "http://localhost");
222
- if (url.pathname.startsWith("/ardy/")) {
266
+ // Only the routes the bridge actually owns: /ardy/ is ALSO a public asset
267
+ // directory (cskel27-rest.json), and those files live in dist/, not behind
268
+ // the sidecar. Same rule as the Vite dev proxy bypass.
269
+ if (/^\/ardy\/(health|bases|generate|footage|extract|motions)(\/|$)/.test(url.pathname)) {
223
270
  proxyToBridge(req, res);
224
271
  return;
225
272
  }
226
- const rel = decodeURIComponent(url.pathname === "/" ? "/index.html" : url.pathname);
273
+ const rel = decodeURIComponent(url.pathname);
227
274
  // normalize + prefix check: a request must not escape dist/.
228
- const target = join(DIST, normalize(rel));
229
- if (!target.startsWith(DIST) || !existsSync(target) || statSync(target).isDirectory()) {
275
+ let target = join(DIST, normalize(rel));
276
+ if (!target.startsWith(DIST)) {
277
+ res.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
278
+ res.end("not found");
279
+ return;
280
+ }
281
+ // The build is multi-page: "/" is the landing and "/app/" is the studio, so a
282
+ // directory has to resolve to its index the way a static host would. Without
283
+ // this the studio 404s and the CLI only ever serves the landing page.
284
+ if (existsSync(target) && statSync(target).isDirectory()) {
285
+ target = join(target, "index.html");
286
+ }
287
+ if (!existsSync(target) || statSync(target).isDirectory()) {
230
288
  res.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
231
289
  res.end("not found");
232
290
  return;
@@ -261,7 +319,10 @@ server.on("error", (err) => {
261
319
  });
262
320
 
263
321
  server.listen(opts.port, opts.host, () => {
264
- const url = `http://${opts.host}:${opts.port}/`;
322
+ // The package exists to open the studio, which the site serves from /app/.
323
+ // Landing on "/" would greet someone who just typed `npx cozyclay` with a
324
+ // marketing page.
325
+ const url = `http://${opts.host}:${opts.port}/app/`;
265
326
  console.log(`CozyClay is running at ${url}`);
266
327
  if (!opts.ardy) console.log("Motion generation: off (--no-ardy).");
267
328
  else if (bridge) console.log(`Motion generation: sidecar running against ${ardyHost}.`);
@@ -272,3 +333,5 @@ server.listen(opts.port, opts.host, () => {
272
333
  );
273
334
  if (opts.open) openBrowser(url);
274
335
  });
336
+
337
+ }
package/dist/CNAME ADDED
@@ -0,0 +1 @@
1
+ cozyclay.org