cozyclay 2.1.0 → 3.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 (583) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +12 -30
  3. package/bin/agent/agent-routes.mjs +40 -113
  4. package/bin/agent/agent-runner.mjs +9 -10
  5. package/bin/agent/cliproxy-provider.mjs +135 -0
  6. package/bin/agent/credential-store.mjs +30 -7
  7. package/bin/agent/pi-tools.mjs +4 -1
  8. package/bin/agent/provider-keys.mjs +32 -0
  9. package/bin/agent/provider-login.mjs +110 -0
  10. package/bin/agent/provider-routes.mjs +99 -0
  11. package/bin/agent/providers.mjs +19 -97
  12. package/bin/agent/script-tool.mjs +17 -4
  13. package/bin/agent/studio-motion-reference.mjs +23 -0
  14. package/bin/agent/studio-prompt.mjs +1 -1
  15. package/bin/agent/studio-rebase-text.mjs +32 -0
  16. package/bin/agent/studio-rebase.mjs +26 -39
  17. package/bin/agent/studio-tools.mjs +9 -28
  18. package/bin/agent/tool-arguments.mjs +49 -0
  19. package/bin/agent/turn-frames.mjs +66 -0
  20. package/bin/codex-auth.mjs +9 -2
  21. package/bin/cozyclay.mjs +10 -116
  22. package/bin/live/cli.mjs +22 -6
  23. package/bin/mcp-runtime.mjs +2 -12
  24. package/bin/package-signature.mjs +0 -4
  25. package/dist/app/index.html +7 -6
  26. package/dist/assets/EXRLoader-CvVIvGVE.js +1 -0
  27. package/dist/assets/analytics-C9sUnndd.js +1 -0
  28. package/dist/assets/app-CCh--1Hc.js +5087 -0
  29. package/dist/assets/app-f-fkV5uP.css +1 -0
  30. package/dist/assets/compile-worker-CkxiD6lH.js +5 -0
  31. package/dist/assets/fflate.module-KbGj5-H6.js +5 -0
  32. package/dist/assets/{first-shot-handoff-BlT33CGf.js → first-shot-handoff-CC4xe4HM.js} +1 -1
  33. package/dist/assets/{landing-BSesrCpL.js → landing-DjHD8u7k.js} +1 -1
  34. package/dist/assets/scene-asset-sync-Hx_FzdOH.js +20 -0
  35. package/dist/assets/scene-asset-sync-_S8NQl5B.css +1 -0
  36. package/dist/assets/workflow-C4yKH1p4.js +179 -0
  37. package/dist/cozyclay-package.json +1 -1
  38. package/dist/index.html +3 -3
  39. package/dist/llms.txt +14 -0
  40. package/dist/sw.js +3 -6
  41. package/dist/workflow/index.html +5 -4
  42. package/mcp/LIVE-PROTOCOL.md +7 -47
  43. package/mcp/README.md +16 -26
  44. package/mcp/live-hub.mjs +6 -10
  45. package/mcp/package.json +1 -3
  46. package/mcp/tool-handlers.mjs +4 -168
  47. package/package.json +3 -22
  48. package/src/App.jsx +174 -2639
  49. package/src/agent-progress.js +79 -0
  50. package/src/agent-turn-mark.js +30 -0
  51. package/src/analytics.js +1 -19
  52. package/src/app-context.js +5 -0
  53. package/src/app-stage.jsx +2 -34
  54. package/src/asset-pane.jsx +6 -5
  55. package/src/camera-block.js +21 -0
  56. package/src/camera-direction.js +120 -0
  57. package/src/character-kind.js +3 -9
  58. package/src/command-bus.js +8 -6
  59. package/src/commands/cast.js +5 -34
  60. package/src/commands/elements/character.js +1 -1
  61. package/src/commands/elements/motion.js +1 -6
  62. package/src/commands/elements/object.js +6 -2
  63. package/src/commands/elements/shot.js +4 -1
  64. package/src/commands/elements.js +38 -14
  65. package/src/commands/index.js +3 -1
  66. package/src/commands/kits.js +37 -0
  67. package/src/commands/motion-timing.js +57 -0
  68. package/src/commands/motion.js +9 -152
  69. package/src/commands/motion3-compile.js +65 -0
  70. package/src/commands/motion3.js +207 -0
  71. package/src/commands/objects.js +6 -4
  72. package/src/commands/shot.js +49 -11
  73. package/src/commands/stage.js +14 -1
  74. package/src/commands/view.js +4 -1
  75. package/src/document-mirrors.js +42 -0
  76. package/src/document-store.js +4 -0
  77. package/src/domains/cast.js +19 -194
  78. package/src/domains/motion/motion-range-pin-rules.js +1 -1
  79. package/src/domains/motion/take-source.js +51 -0
  80. package/src/domains/motion.js +60 -1838
  81. package/src/domains/scenes.js +12 -55
  82. package/src/domains/shots.js +2 -2
  83. package/src/domains/stage.js +4 -2
  84. package/src/draft-ghost.js +46 -0
  85. package/src/draft-ghost.jsx +129 -0
  86. package/src/dualview.jsx +4 -3
  87. package/src/effects/EffectsLayer.jsx +112 -0
  88. package/src/effects/effect-meshes.js +232 -0
  89. package/src/effects/effect-record.js +103 -0
  90. package/src/effects/emitter.js +59 -0
  91. package/src/effects/simulate.js +261 -0
  92. package/src/effects/state.js +59 -0
  93. package/src/execution-telemetry.js +2 -3
  94. package/src/first-success-guide.jsx +5 -5
  95. package/src/ghost-set.js +257 -0
  96. package/src/held-object-edit.jsx +113 -0
  97. package/src/held-object-pose.js +175 -0
  98. package/src/hierarchy-model.js +1 -1
  99. package/src/hierarchy-panel.jsx +1 -1
  100. package/src/imported-mesh.jsx +103 -0
  101. package/src/kits/held.js +84 -0
  102. package/src/kits/index.js +70 -0
  103. package/src/kits/smoking.js +57 -0
  104. package/src/light-blockers.js +93 -0
  105. package/src/motion/beat-board-model.js +84 -0
  106. package/src/motion/beat-board.css +124 -0
  107. package/src/motion/beat-board.jsx +59 -0
  108. package/src/motion/center-of-mass.js +66 -0
  109. package/src/motion/fix-collisions.js +850 -0
  110. package/src/motion/physics-review.js +118 -0
  111. package/src/{ardy → motion}/physics-support.js +1 -76
  112. package/src/motion/rig-snapshot.js +22 -0
  113. package/src/motion/take-segments.jsx +140 -0
  114. package/src/{ardy → motion}/timeline-coordinates.js +0 -21
  115. package/src/{ardy → motion}/timeline.css +1 -2
  116. package/src/{ardy → motion}/timeline.jsx +48 -419
  117. package/src/motion/waypoints.js +76 -0
  118. package/src/motion3/beats.js +83 -0
  119. package/src/motion3/body.js +158 -0
  120. package/src/motion3/bones.js +47 -0
  121. package/src/motion3/carried.js +47 -0
  122. package/src/motion3/compile-job.js +75 -0
  123. package/src/motion3/compile-worker.js +10 -0
  124. package/src/motion3/compiler/anchors.js +105 -0
  125. package/src/motion3/compiler/arm-orient.js +128 -0
  126. package/src/motion3/compiler/channels.js +125 -0
  127. package/src/motion3/compiler/compile.js +205 -0
  128. package/src/motion3/compiler/gait-rhythm.js +97 -0
  129. package/src/motion3/compiler/grip.js +171 -0
  130. package/src/motion3/compiler/head-steady.js +48 -0
  131. package/src/motion3/compiler/hold.js +134 -0
  132. package/src/motion3/compiler/idle.js +113 -0
  133. package/src/motion3/compiler/limbs.js +170 -0
  134. package/src/motion3/compiler/math.js +72 -0
  135. package/src/motion3/compiler/pose.js +162 -0
  136. package/src/motion3/compiler/quat.js +49 -0
  137. package/src/motion3/compiler/skeleton.js +74 -0
  138. package/src/motion3/compiler/validate-common.js +32 -0
  139. package/src/motion3/compiler/validate-goals.js +118 -0
  140. package/src/motion3/compiler/validate-objects.js +143 -0
  141. package/src/motion3/compiler/validate-parts.js +116 -0
  142. package/src/motion3/compiler/validate.js +122 -0
  143. package/src/motion3/compiler/vocab.js +73 -0
  144. package/src/motion3/compiler/walk-pelvis.js +275 -0
  145. package/src/motion3/compiler/walk.js +207 -0
  146. package/src/motion3/compiler/wrist-clamp.js +32 -0
  147. package/src/motion3/delta.js +47 -0
  148. package/src/motion3/describe.js +174 -0
  149. package/src/motion3/docs.js +27 -0
  150. package/src/motion3/edit-carry.js +21 -0
  151. package/src/motion3/fix/ease.js +16 -0
  152. package/src/motion3/fix/ground.js +37 -0
  153. package/src/motion3/fix/index.js +52 -0
  154. package/src/motion3/fix/push.js +71 -0
  155. package/src/motion3/fix/reach.js +46 -0
  156. package/src/motion3/fix/retime.js +79 -0
  157. package/src/motion3/fix/self.js +211 -0
  158. package/src/motion3/fix/slide.js +70 -0
  159. package/src/motion3/fix/turn.js +51 -0
  160. package/src/motion3/follow.js +39 -0
  161. package/src/motion3/free-motion.js +173 -0
  162. package/src/motion3/grip-choice.js +130 -0
  163. package/src/motion3/hold-plan.js +157 -0
  164. package/src/motion3/json-patch.js +77 -0
  165. package/src/motion3/key-aim.js +105 -0
  166. package/src/motion3/key-edit.js +82 -0
  167. package/src/motion3/lenient.js +127 -0
  168. package/src/motion3/object-keys.js +236 -0
  169. package/src/motion3/object-pose.js +182 -0
  170. package/src/motion3/object-tracks.js +12 -0
  171. package/src/motion3/pipeline.js +102 -0
  172. package/src/motion3/playback.js +51 -0
  173. package/src/motion3/probes.js +91 -0
  174. package/src/motion3/qa/body-checks.js +34 -0
  175. package/src/motion3/qa/check-names.js +14 -0
  176. package/src/motion3/qa/checks.js +121 -0
  177. package/src/motion3/qa/contact-checks.js +51 -0
  178. package/src/motion3/qa/explain.js +80 -0
  179. package/src/motion3/qa/fmt.js +5 -0
  180. package/src/motion3/qa/foot-checks.js +72 -0
  181. package/src/motion3/qa/geometry.js +77 -0
  182. package/src/motion3/qa/goals.js +191 -0
  183. package/src/motion3/qa/ground.js +60 -0
  184. package/src/motion3/qa/hints-contact.js +179 -0
  185. package/src/motion3/qa/hints-goal.js +160 -0
  186. package/src/motion3/qa/hints-knee.js +24 -0
  187. package/src/motion3/qa/hints-motion.js +209 -0
  188. package/src/motion3/qa/hints-object.js +91 -0
  189. package/src/motion3/qa/index.js +42 -0
  190. package/src/motion3/qa/key-checks.js +82 -0
  191. package/src/motion3/qa/near.js +96 -0
  192. package/src/motion3/qa/object-checks.js +135 -0
  193. package/src/motion3/qa/patch.js +161 -0
  194. package/src/motion3/qa/severity.js +38 -0
  195. package/src/motion3/qa/spec-checks.js +65 -0
  196. package/src/motion3/qa/style.js +218 -0
  197. package/src/motion3/qa/wrist-checks.js +69 -0
  198. package/src/motion3/qa/wrist-obs.js +60 -0
  199. package/src/motion3/refs.js +120 -0
  200. package/src/motion3/repair-tune.js +121 -0
  201. package/src/motion3/repair.js +83 -0
  202. package/src/motion3/report.js +67 -0
  203. package/src/motion3/rigs/index.js +14 -0
  204. package/src/motion3/rigs/x-bot-tpose-body.json +1 -0
  205. package/src/motion3/rigs/x-bot-tpose.json +1 -0
  206. package/src/motion3/rigs/y-bot-tpose-body.json +1 -0
  207. package/src/motion3/rigs/y-bot-tpose.json +1 -0
  208. package/src/motion3/scene.js +60 -0
  209. package/src/motion3/schema/brief.js +89 -0
  210. package/src/motion3/schema/fields.js +44 -0
  211. package/src/motion3/schema/spec-examples.js +46 -0
  212. package/src/motion3/schema/topics.js +111 -0
  213. package/src/motion3/schema/types.js +147 -0
  214. package/src/motion3/search.js +117 -0
  215. package/src/motion3/second-hand.js +112 -0
  216. package/src/motion3/skills/basic.js +82 -0
  217. package/src/motion3/skills/book.js +76 -0
  218. package/src/motion3/skills/car.js +145 -0
  219. package/src/motion3/skills/frames-auto.js +29 -0
  220. package/src/motion3/skills/index.js +83 -0
  221. package/src/motion3/skills/info.js +65 -0
  222. package/src/motion3/skills/smoke-kit.js +109 -0
  223. package/src/motion3/skills/smoke.js +160 -0
  224. package/src/motion3/spec-store.js +59 -0
  225. package/src/motion3/take-edit.js +155 -0
  226. package/src/motion3/take.js +63 -0
  227. package/src/motion3/timeline.js +127 -0
  228. package/src/motion3/views.js +121 -0
  229. package/src/motion3/walk-plan.js +119 -0
  230. package/src/object-catalog.jsx +7 -1
  231. package/src/object-colors.js +98 -0
  232. package/src/object-gizmo-parts.js +115 -0
  233. package/src/object-gizmo.jsx +37 -122
  234. package/src/object-glow.js +139 -0
  235. package/src/object-hidden.js +33 -0
  236. package/src/object-look.js +196 -0
  237. package/src/object-size.js +10 -0
  238. package/src/object-travel.js +71 -6
  239. package/src/panels/CameraPanel.jsx +7 -7
  240. package/src/panels/HdrEnvironmentControls.jsx +59 -0
  241. package/src/panels/LightPanel.jsx +25 -4
  242. package/src/panels/ObjectLookPanel.jsx +88 -0
  243. package/src/panels/PoseImagePanel.jsx +1 -1
  244. package/src/panels/PosePanel.jsx +2 -17
  245. package/src/panels/RigControlPanel.jsx +5 -53
  246. package/src/panels/SubjectBox.jsx +4 -1
  247. package/src/panels/details.css +14 -0
  248. package/src/posestudio.jsx +4 -27
  249. package/src/project-browser.jsx +3 -4
  250. package/src/project-resources.js +18 -31
  251. package/src/project.js +13 -104
  252. package/src/props.jsx +25 -280
  253. package/src/rail-dot-drag.js +23 -0
  254. package/src/render-passes.js +10 -0
  255. package/src/resource-status.jsx +1 -0
  256. package/src/result-modal.jsx +4 -19
  257. package/src/room.jsx +20 -12
  258. package/src/scene-assets.js +8 -6
  259. package/src/scene-light-place.js +72 -0
  260. package/src/scene-lights.jsx +148 -0
  261. package/src/scene-objects.js +31 -139
  262. package/src/scenes.js +15 -105
  263. package/src/semantic-edit.js +2 -5
  264. package/src/set-pieces.jsx +183 -0
  265. package/src/settings-menu.jsx +3 -11
  266. package/src/shell/BottomDock.jsx +11 -53
  267. package/src/shell/CompositionGuideButton.jsx +20 -0
  268. package/src/shell/DetailsSlot.jsx +16 -200
  269. package/src/shell/GhostsMenuGroup.jsx +74 -0
  270. package/src/shell/LibrarySlot.jsx +1 -3
  271. package/src/shell/MenuBar.jsx +3 -3
  272. package/src/shell/PreferencesDialog.jsx +15 -264
  273. package/src/shell/PreferencesSlot.jsx +2 -8
  274. package/src/shell/ShotPreviewHeader.jsx +17 -0
  275. package/src/shell/TopBar.jsx +5 -83
  276. package/src/shell/ViewportToolbar.jsx +23 -93
  277. package/src/shell/agent-glass.css +19 -6
  278. package/src/shell/details-selection.js +42 -0
  279. package/src/shell/ghosts-menu.css +22 -0
  280. package/src/shell/glass-regions.css +29 -3
  281. package/src/shell/preferences.css +6 -1
  282. package/src/shell/viewport.css +12 -0
  283. package/src/shot-authoring.js +4 -7
  284. package/src/soft-shadows.js +37 -0
  285. package/src/stage-attach-frames.js +12 -12
  286. package/src/stage-canvas-rigs.jsx +3 -3
  287. package/src/stage-capture.jsx +42 -8
  288. package/src/stage-characters.jsx +22 -216
  289. package/src/stage-editor-gizmos.jsx +6 -6
  290. package/src/stage-environment.js +93 -0
  291. package/src/stage-hdr-builtins.js +107 -0
  292. package/src/stage-hdr-image.js +116 -0
  293. package/src/stage-hdr-library.js +70 -0
  294. package/src/stage-hdr-map.js +94 -0
  295. package/src/stage-hdr.js +130 -0
  296. package/src/stage-lighting.js +149 -0
  297. package/src/stage-occlusion.js +210 -0
  298. package/src/stage-sky.jsx +159 -0
  299. package/src/stage-startup-defaults.js +5 -9
  300. package/src/studio-actions.js +12 -14
  301. package/src/studio-agent-commands.js +46 -16
  302. package/src/studio-agent-motion.js +9 -9
  303. package/src/studio-agent-protocol.js +46 -73
  304. package/src/studio-app-binding.js +29 -45
  305. package/src/studio-asset-list.js +17 -0
  306. package/src/studio-contact-sheet.js +37 -5
  307. package/src/studio-elements.js +27 -7
  308. package/src/studio-entity-bounds.js +18 -0
  309. package/src/studio-error-codes.js +8 -0
  310. package/src/studio-export-framing.js +152 -0
  311. package/src/studio-lighting-check.js +103 -0
  312. package/src/studio-motion-visual.js +150 -0
  313. package/src/studio-schema-errors.js +80 -0
  314. package/src/studio-support-gap.js +74 -0
  315. package/src/styles.css +1 -19
  316. package/src/timeline-defaults.js +5 -0
  317. package/src/timeline-extent.js +8 -20
  318. package/src/tutorial-walk.js +17 -0
  319. package/src/ui-scrub.js +1 -1
  320. package/src/use-shot-camera-tracks.js +12 -0
  321. package/src/view-ghosts.js +97 -0
  322. package/src/view-ghosts.jsx +49 -0
  323. package/src/workflow/AgentPanel.jsx +47 -166
  324. package/src/workflow/AgentProgressCard.jsx +107 -0
  325. package/src/workflow/AgentReplyText.jsx +37 -0
  326. package/src/workflow/AgentTurnSteps.jsx +84 -0
  327. package/src/workflow/LoginPanel.jsx +140 -0
  328. package/src/workflow/WorkflowBuilder.jsx +7 -23
  329. package/src/workflow/agent-client.js +54 -51
  330. package/src/workflow/agent-panel.css +71 -1
  331. package/src/workflow/agent-progress-card.css +167 -0
  332. package/src/workflow/agent-progress-view.js +47 -0
  333. package/src/workflow/agent-turn-steps.css +113 -0
  334. package/src/workflow/agent-turn.js +191 -0
  335. package/src/workflow/login-client.js +34 -0
  336. package/src/workflow/motion-input.js +18 -31
  337. package/src/workflow/node-schema.js +1 -1
  338. package/src/workflow/reply-markdown.js +69 -0
  339. package/src/workflow/scene-asset-sync.js +8 -8
  340. package/tools/agent-session-stats.mjs +61 -0
  341. package/tools/dev-full.mjs +5 -56
  342. package/tools/eslint-baseline.json +12 -13
  343. package/tools/headless-studio.mjs +85 -0
  344. package/tools/knip-baseline.json +0 -179
  345. package/tools/loc-baseline.json +33 -83
  346. package/tools/motion3/extract-body.mjs +103 -0
  347. package/tools/motion3/extract-rig.mjs +85 -0
  348. package/tools/process-supervisor.mjs +0 -88
  349. package/tools/run-tests.mjs +9 -124
  350. package/bin/agent/motion-runtime.mjs +0 -76
  351. package/dist/ardy/cskel27-rest.json +0 -557
  352. package/dist/assets/analytics-B41FmPYI.js +0 -1
  353. package/dist/assets/app-Do-Og5Pu.css +0 -1
  354. package/dist/assets/app-DwP-tl2x.js +0 -4920
  355. package/dist/assets/config-Bx7pYsD9.js +0 -1
  356. package/dist/assets/config-DeoFTYzb.css +0 -1
  357. package/dist/assets/demo-Dt0qZfS7.js +0 -1
  358. package/dist/assets/scene-asset-sync-BCWDJB1d.js +0 -19
  359. package/dist/assets/scene-asset-sync-DjJ_cJ2R.css +0 -1
  360. package/dist/assets/ticket-jqMhqL88.js +0 -1
  361. package/dist/assets/workflow-Br-K7Srs.js +0 -179
  362. package/dist/demo/walk-then-stop.npz +0 -0
  363. package/mcp/ardy-prompts.mjs +0 -218
  364. package/src/ardy/auto-fix-panel.css +0 -108
  365. package/src/ardy/auto-physics.js +0 -1194
  366. package/src/ardy/client.js +0 -153
  367. package/src/ardy/convert.js +0 -313
  368. package/src/ardy/cskel27-neutral.js +0 -39
  369. package/src/ardy/cskel27.js +0 -77
  370. package/src/ardy/export.js +0 -165
  371. package/src/ardy/fix-collisions.js +0 -2257
  372. package/src/ardy/foot-lock.js +0 -230
  373. package/src/ardy/motion-calibration.js +0 -118
  374. package/src/ardy/motion-edit.js +0 -213
  375. package/src/ardy/motion-url.js +0 -55
  376. package/src/ardy/mp4-duration.js +0 -102
  377. package/src/ardy/npz.js +0 -595
  378. package/src/ardy/physics-panel.css +0 -21
  379. package/src/ardy/physics-panel.jsx +0 -89
  380. package/src/ardy/physics-refine.js +0 -111
  381. package/src/ardy/physics-review.js +0 -567
  382. package/src/ardy/physics-temporal.js +0 -54
  383. package/src/ardy/platform-fit-panel.css +0 -64
  384. package/src/ardy/platform-fit-panel.jsx +0 -41
  385. package/src/ardy/platform-fit.js +0 -326
  386. package/src/ardy/playback.js +0 -711
  387. package/src/ardy/pose-pin.js +0 -97
  388. package/src/ardy/prompt-clips.js +0 -30
  389. package/src/ardy/retime.js +0 -211
  390. package/src/ardy/root-drop.js +0 -369
  391. package/src/ardy/timeline-resize.js +0 -13
  392. package/src/ardy/to-cskel27.js +0 -225
  393. package/src/ardy/trim.js +0 -33
  394. package/src/ardy/waypoints.js +0 -369
  395. package/src/ardy-bridge-contract.js +0 -281
  396. package/src/domains/motion/motion-video-capture.js +0 -664
  397. package/src/i2v-motion-client.js +0 -77
  398. package/src/i2v-motion-studio.jsx +0 -180
  399. package/src/line-edit.js +0 -1348
  400. package/src/motion/generation.js +0 -105
  401. package/src/motion-readiness-ui.jsx +0 -67
  402. package/src/motion-readiness.js +0 -40
  403. package/src/motion-resources.js +0 -177
  404. package/src/motion-store.js +0 -65
  405. package/src/motion-trail.js +0 -601
  406. package/src/multimodel-ingest.js +0 -394
  407. package/src/panels/PromptBlocksPanel.jsx +0 -444
  408. package/src/panels/VideoCapturePanel.jsx +0 -181
  409. package/src/pose-extract/browser.js +0 -42
  410. package/src/pose-extract/detector.js +0 -100
  411. package/src/pose-extract/fit.js +0 -227
  412. package/src/pose-extract/image-frame.js +0 -51
  413. package/src/pose-extract/index.js +0 -58
  414. package/src/pose-extract/keyframes.js +0 -74
  415. package/src/pose-extract/landmarks.js +0 -162
  416. package/src/pose-extract/mirror.js +0 -153
  417. package/src/pose-extract/take.js +0 -131
  418. package/src/pose-extract/video-frames.js +0 -91
  419. package/src/take-recipe.js +0 -165
  420. package/src/trail-key-conflicts.js +0 -39
  421. package/src/trail-pick.js +0 -59
  422. package/src/use-i2v-capture-modal.js +0 -15
  423. package/tools/ardy/BRIDGE.md +0 -37
  424. package/tools/ardy/GVHMR-NPZ.md +0 -68
  425. package/tools/ardy/README.md +0 -124
  426. package/tools/ardy/__pycache__/cclay_gvhmr_worker.cpython-313.pyc +0 -0
  427. package/tools/ardy/artifacts.mjs +0 -34
  428. package/tools/ardy/bridge.mjs +0 -1732
  429. package/tools/ardy/bvh-cskel27.mjs +0 -1265
  430. package/tools/ardy/cclay_constrained_generate.py +0 -561
  431. package/tools/ardy/cclay_gvhmr_worker.py +0 -264
  432. package/tools/ardy/cclay_motion_edit.py +0 -510
  433. package/tools/ardy/cclay_sequence_generate.py +0 -705
  434. package/tools/ardy/cclay_worker.py +0 -304
  435. package/tools/ardy/dump-npz.py +0 -205
  436. package/tools/ardy/extract-rest.mjs +0 -299
  437. package/tools/ardy/extract.mjs +0 -507
  438. package/tools/ardy/footage.mjs +0 -467
  439. package/tools/ardy/gvhmr-floor.mjs +0 -102
  440. package/tools/ardy/gvhmr-to-cskel27.mjs +0 -21
  441. package/tools/ardy/gvhmr_fastpath.py +0 -168
  442. package/tools/ardy/gvhmr_trajectory.py +0 -240
  443. package/tools/ardy/merge-text-encoder.py +0 -160
  444. package/tools/ardy/mocap-metrics.mjs +0 -200
  445. package/tools/ardy/mocap-quality-gate.mjs +0 -110
  446. package/tools/ardy/motion-stabilize.mjs +0 -348
  447. package/tools/ardy/npz.mjs +0 -414
  448. package/tools/ardy/pose-to-npz.mjs +0 -106
  449. package/tools/ardy/prompt-limits.mjs +0 -5
  450. package/tools/ardy/run-edit-on-box.sh +0 -73
  451. package/tools/ardy/run-local.mjs +0 -233
  452. package/tools/ardy/run-on-box.sh +0 -593
  453. package/tools/ardy/run-sequence-on-box.sh +0 -177
  454. package/tools/ardy/runners/gvhmr-worker.mjs +0 -206
  455. package/tools/ardy/runners/index.mjs +0 -18
  456. package/tools/ardy/runners/local.mjs +0 -455
  457. package/tools/ardy/runners/proc.mjs +0 -125
  458. package/tools/ardy/runners/remote.mjs +0 -252
  459. package/tools/ardy/setup-local.mjs +0 -189
  460. package/tools/ardy/setup-text-encoder-on-box.sh +0 -93
  461. package/tools/ardy/setup-text-encoder.py +0 -306
  462. package/tools/ardy/smpl-cskel27.mjs +0 -178
  463. package/tools/ardy/visual-qa.mjs +0 -196
  464. package/tools/ardy/vq-car.mjs +0 -52
  465. package/tools/bench/EXP3.md +0 -61
  466. package/tools/bench/cclay_bench_extract_incam.py +0 -125
  467. package/tools/bench/cclay_bench_extract_obs.py +0 -204
  468. package/tools/bench/cclay_bench_runner.py +0 -42
  469. package/tools/bench/cube-contact.mjs +0 -162
  470. package/tools/bench/exp3.mjs +0 -152
  471. package/tools/bench/extract-bench-lib.mjs +0 -216
  472. package/tools/bench/extract-bench.mjs +0 -302
  473. package/tools/bench/fal-generate.mjs +0 -88
  474. package/tools/bench/fit/README.md +0 -189
  475. package/tools/bench/fit/camera.mjs +0 -59
  476. package/tools/bench/fit/contact.mjs +0 -419
  477. package/tools/bench/fit/footlock.mjs +0 -234
  478. package/tools/bench/fit/motion.mjs +0 -85
  479. package/tools/bench/fit/pin.mjs +0 -27
  480. package/tools/bench/fit/remote.mjs +0 -105
  481. package/tools/bench/fit-bench.mjs +0 -126
  482. package/tools/bench/fit-sanity.mjs +0 -45
  483. package/tools/bench/metrics.mjs +0 -313
  484. package/tools/bench/obs/depth.mjs +0 -258
  485. package/tools/bench/obs/extrinsics.mjs +0 -175
  486. package/tools/bench/obs/fit_mannequin_betas.py +0 -340
  487. package/tools/bench/obs/ground.mjs +0 -294
  488. package/tools/bench/obs/heading.mjs +0 -151
  489. package/tools/bench/obs/ladder.mjs +0 -555
  490. package/tools/bench/obs/mannequin-betas.json +0 -124
  491. package/tools/bench/obs/remote.mjs +0 -83
  492. package/tools/bench/obs/rest_joints.py +0 -52
  493. package/tools/bench/obs/ybot-targets.mjs +0 -49
  494. package/tools/bench/obs-bench.mjs +0 -520
  495. package/tools/bench/score.mjs +0 -343
  496. package/tools/bench/summarize.mjs +0 -86
  497. package/tools/demo-worker/README.md +0 -137
  498. package/tools/demo-worker/api-client.mjs +0 -233
  499. package/tools/demo-worker/generate.mjs +0 -301
  500. package/tools/demo-worker/index.mjs +0 -466
  501. package/tools/demo-worker/sign-core.mjs +0 -112
  502. package/tools/demo-worker/sign.mjs +0 -161
  503. package/tools/gt-render/browser.mjs +0 -159
  504. package/tools/gt-render/camera-math.mjs +0 -276
  505. package/tools/gt-render/page.mjs +0 -267
  506. package/tools/gt-render/render.mjs +0 -514
  507. package/tools/gt-render/scene-box.mjs +0 -31
  508. package/tools/gt-render/take-transform.mjs +0 -87
  509. package/tools/kimodo/compare-seam.mjs +0 -108
  510. package/tools/kimodo/constraints.mjs +0 -244
  511. package/tools/kimodo/edit.mjs +0 -259
  512. package/tools/kimodo/effector-constraints.mjs +0 -200
  513. package/tools/kimodo/generate.mjs +0 -646
  514. package/tools/kimodo/local-output.mjs +0 -265
  515. package/tools/kimodo/measure-pose.mjs +0 -65
  516. package/tools/kimodo/measure-preserve.mjs +0 -899
  517. package/tools/kimodo/measure-waypoints.mjs +0 -55
  518. package/tools/kimodo/mlx-generate.py +0 -111
  519. package/tools/kimodo/pose-constraints.mjs +0 -248
  520. package/tools/kimodo/preserve-mask.mjs +0 -543
  521. package/tools/kimodo/read-npz.mjs +0 -189
  522. package/tools/kimodo/run-edit-on-box.mjs +0 -155
  523. package/tools/kimodo/run-sequence-on-box.mjs +0 -178
  524. package/tools/kimodo/runner.mjs +0 -284
  525. package/tools/kimodo/seam-batch.mjs +0 -77
  526. package/tools/kimodo/setup-local.mjs +0 -30
  527. package/tools/kimodo/setup-on-box.sh +0 -339
  528. package/tools/kimodo/soma77-to-cskel27.mjs +0 -305
  529. package/tools/morphgs/assets/gen_truth.py +0 -39
  530. package/tools/morphgs/assets/mesh_ori_rig.txt +0 -27
  531. package/tools/morphgs/assets/playback-check.mjs +0 -30
  532. package/tools/morphgs/demo-gate.sh +0 -26
  533. package/tools/morphgs/fbx2morphgs.mjs +0 -68
  534. package/tools/morphgs/morphgs-to-cskel27.mjs +0 -105
  535. package/tools/morphgs/patches/preprocess_src-none-mode.patch +0 -76
  536. package/tools/morphgs/setup-on-cluster.sh +0 -126
  537. package/tools/projflow/driver.py +0 -1069
  538. package/tools/projflow/generate.mjs +0 -805
  539. package/tools/projflow/hml22-to-cskel27.mjs +0 -735
  540. package/tools/projflow/line-edit-job.mjs +0 -547
  541. package/tools/projflow/replay.mjs +0 -452
  542. package/tools/projflow/runner.mjs +0 -269
  543. package/tools/projflow/service.mjs +0 -742
  544. package/tools/track/DESIGN.md +0 -513
  545. package/tools/track/backfill-provenance.mjs +0 -116
  546. package/tools/track/budget.mjs +0 -8
  547. package/tools/track/check-rig.mjs +0 -209
  548. package/tools/track/diagnostics.schema.json +0 -60
  549. package/tools/track/export-rig.mjs +0 -256
  550. package/tools/track/fallback.mjs +0 -7
  551. package/tools/track/fk-parity-fixture.mjs +0 -161
  552. package/tools/track/gate.mjs +0 -349
  553. package/tools/track/masks.mjs +0 -318
  554. package/tools/track/metrics.mjs +0 -201
  555. package/tools/track/publish-obs.mjs +0 -108
  556. package/tools/track/py/check_env.py +0 -61
  557. package/tools/track/py/eval_lr.py +0 -229
  558. package/tools/track/py/lr_viterbi.py +0 -294
  559. package/tools/track/py/masks.py +0 -405
  560. package/tools/track/py/objective.py +0 -382
  561. package/tools/track/py/rig.py +0 -508
  562. package/tools/track/py/scene.py +0 -326
  563. package/tools/track/py/test_joint_indices.py +0 -123
  564. package/tools/track/py/test_lr_viterbi.py +0 -195
  565. package/tools/track/py/test_masks.py +0 -229
  566. package/tools/track/py/test_rig.py +0 -288
  567. package/tools/track/py/test_scene.py +0 -354
  568. package/tools/track/py/test_track.py +0 -328
  569. package/tools/track/py/track.py +0 -411
  570. package/tools/track/remote.mjs +0 -140
  571. package/tools/track/rig-dump.mjs +0 -227
  572. package/tools/track/run-box-tests.mjs +0 -14
  573. package/tools/track/run-box.mjs +0 -168
  574. package/tools/track/setup-box.sh +0 -59
  575. package/tools/track/study-2d.mjs +0 -728
  576. /package/src/{ardy → motion}/collision-blockers.js +0 -0
  577. /package/src/{ardy → motion}/ground.js +0 -0
  578. /package/src/{ardy → motion}/ik-drag.js +0 -0
  579. /package/src/{ardy → motion}/ik-key-json.js +0 -0
  580. /package/src/{ardy → motion}/ik.js +0 -0
  581. /package/src/{ardy → motion}/physics-surface.js +0 -0
  582. /package/src/{ardy → motion}/playback-clock.js +0 -0
  583. /package/src/{ardy → motion}/range-pin.js +0 -0
@@ -1 +1 @@
1
- {"payload":"{\"distribution\":\"npm\",\"package\":\"cozyclay\",\"version\":\"2.1.0\",\"repository\":\"NomaDamas/CozyClay\",\"content_sha256\":\"94d0d33855916922202e0ff1c4afc9aff0e6db281adae8072ae72da7936dd906\"}","signature":"BDrFE1pch5PcqsC6Q9eeqhgX+hfAdOLbJEbdZGM+upY9ACMIItqHsHEmqan1Qkl1i636NrVs0e0zGH7cVmFPCQ=="}
1
+ {"payload":"{\"distribution\":\"npm\",\"package\":\"cozyclay\",\"version\":\"3.0.0\",\"repository\":\"NomaDamas/CozyClay\",\"content_sha256\":\"e6a50c77650f2894d8154267dec8faafb86cad41e859b2594f233d5a18348530\"}","signature":"rwtYOUdZUQo57FluVUioxvNg+gKzRgBC38gyKcd7GIrm5nhq3iff5eV90XV7YFAJfVHn466qu3iLBsnjKkpIDA=="}
package/dist/index.html CHANGED
@@ -301,9 +301,9 @@
301
301
  .btn, a.card, .seg button, .tutorial-steps li { transition: none; }
302
302
  }
303
303
  </style>
304
- <script type="module" crossorigin src="/assets/landing-BSesrCpL.js"></script>
305
- <link rel="modulepreload" crossorigin href="/assets/analytics-B41FmPYI.js">
306
- <link rel="modulepreload" crossorigin href="/assets/first-shot-handoff-BlT33CGf.js">
304
+ <script type="module" crossorigin src="/assets/landing-DjHD8u7k.js"></script>
305
+ <link rel="modulepreload" crossorigin href="/assets/analytics-C9sUnndd.js">
306
+ <link rel="modulepreload" crossorigin href="/assets/first-shot-handoff-CC4xe4HM.js">
307
307
  </head>
308
308
  <body>
309
309
  <header class="site">
package/dist/llms.txt CHANGED
@@ -11,6 +11,20 @@
11
11
  - [Camera control for AI video](https://cozyclay.org/ai-camera-control/): why camera prompts drift and what the models actually accept.
12
12
  - [Privacy](https://cozyclay.org/privacy/): analytics and telemetry disclosure.
13
13
 
14
+ ## Agent loop
15
+
16
+ 1. Install and open the Studio: `npx cozyclay`.
17
+ 2. Wait for a live editor: `cclay live status --wait`.
18
+ 3. Read before editing: `cclay live inspect --scope scene` or `--scope catalogue`.
19
+ 4. Apply one semantic batch with `cclay live arrange-objects`, `arrange-characters`, `frame-shot`, or `patch`.
20
+ 5. Verify the result. For a whole shot, use `cclay live verify --targets <id> --checks framing --range whole_clip --visual contact_sheet --out verify.png`.
21
+ 6. Use `--strict` when sampled framing findings should make the command fail. A sampled result is evidence for the returned frames, not proof of every frame.
22
+ 7. Read the receipt before retrying. `UNCERTAIN_APPLY` means reconcile or inspect first. `STALE_HANDLE` means status and workspace selection again. `NOT_IN_MODE` means switch Storyboard/Animation before using motion tools.
23
+
24
+ The Studio, MCP server and `cclay live` use the same command contract. `script` can call several tools in one QuickJS transaction for computed layouts. Every authored edit returns a receipt and can be undone.
25
+
26
+ For source-checkout CI, start the same Studio in owned headless Chrome with `node tools/headless-studio.mjs --project shot.cclayproject --port 5920 --live-port 5924`; then point `COZYCLAY_LIVE_PORT=5924 cclay live ...` at it. The launcher owns the Vite and Chrome children and cleans them up on exit.
27
+
14
28
  ## Source
15
29
 
16
30
  - GitHub: https://github.com/NomaDamas/CozyClay
package/dist/sw.js CHANGED
@@ -9,7 +9,8 @@ const CACHE_PREFIX = "cozyclay-pwa-";
9
9
  // v6 also: hosted demo and ticket pages are network-only; never freeze queue state.
10
10
  // v7: force-refresh the asset cache — v6 clients were holding a stale app shell
11
11
  // (the html-flex crash-screen regression) and never re-fetching it.
12
- const CACHE_NAME = `${CACHE_PREFIX}v7`;
12
+ // v8: CozyClay 3 drops the shipped walk clip (motion is compiled in the studio).
13
+ const CACHE_NAME = `${CACHE_PREFIX}v8`;
13
14
  // The installable app is the studio, not the landing page.
14
15
  const APP_SHELL = "/app/";
15
16
  const CORE_ASSETS = [
@@ -23,7 +24,6 @@ const CORE_ASSETS = [
23
24
  "./icons/apple-touch-icon.png",
24
25
  "./favicon.ico",
25
26
  "./fonts/inter-latin.woff2",
26
- "./demo/walk-then-stop.npz",
27
27
  "./models/x-bot-tpose.fbx",
28
28
  "./models/y-bot-tpose.fbx",
29
29
  ];
@@ -79,14 +79,11 @@ self.addEventListener("message", (event) => {
79
79
  self.addEventListener("fetch", (event) => {
80
80
  const { request } = event;
81
81
  const url = new URL(request.url);
82
- // The composer and ticket are live API surfaces. A stale shell would either
83
- // submit with an old Turnstile key or show a frozen queue position.
84
- if (url.pathname.startsWith("/d/") || url.pathname.startsWith("/demo/")) return;
85
82
  // Landing-page playground presets are edited in place; a cache-first hit
86
83
  // would pin the first version a visitor ever saw.
87
84
  if (url.pathname.startsWith("/scenes/")) return;
88
85
  if (request.method !== "GET") return;
89
- if (url.origin !== self.location.origin || url.pathname.includes("/ardy/")) return;
86
+ if (url.origin !== self.location.origin) return;
90
87
  if (request.headers.has("range")) {
91
88
  event.respondWith((async () => {
92
89
  try {
@@ -8,11 +8,12 @@
8
8
  <meta name="theme-color" content="#101116" />
9
9
  <meta name="description" content="CozyClay visual workflow builder" />
10
10
  <title>CozyClay Workflow</title>
11
- <script type="module" crossorigin src="/assets/workflow-Br-K7Srs.js"></script>
11
+ <script type="module" crossorigin src="/assets/workflow-C4yKH1p4.js"></script>
12
12
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-hePW80VL.js">
13
- <link rel="modulepreload" crossorigin href="/assets/analytics-B41FmPYI.js">
14
- <link rel="modulepreload" crossorigin href="/assets/scene-asset-sync-BCWDJB1d.js">
15
- <link rel="stylesheet" crossorigin href="/assets/scene-asset-sync-DjJ_cJ2R.css">
13
+ <link rel="modulepreload" crossorigin href="/assets/analytics-C9sUnndd.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/fflate.module-KbGj5-H6.js">
15
+ <link rel="modulepreload" crossorigin href="/assets/scene-asset-sync-Hx_FzdOH.js">
16
+ <link rel="stylesheet" crossorigin href="/assets/scene-asset-sync-_S8NQl5B.css">
16
17
  <link rel="stylesheet" crossorigin href="/assets/workflow-DRdwoDBT.css">
17
18
  </head>
18
19
  <body>
@@ -43,28 +43,15 @@ server -> editor, one per command:
43
43
 
44
44
  { "type": "cmd", "id": "<opaque string>", "name": "<command>", "args": { ... } }
45
45
 
46
- server -> editor, for an MCP-owned motion job state or terminal outcome (and again
47
- on reconnect while retained). A completed event follows the editor's successful
48
- `load_motion` acknowledgement:
49
-
50
- { "type": "event", "name": "motion_job", "payload": { "taskId", "status", "createdAt", "lastUpdatedAt", "ttlMs", "pollIntervalMs", "outcome?" } }
51
-
52
- editor -> server, to cancel its own active job before editor delivery:
53
-
54
- { "type": "event", "name": "motion_job_cancel", "payload": { "taskId": "<opaque task id>" } }
55
-
56
46
  editor -> server, one per command, echoing `id`:
57
47
 
58
48
  { "type": "result", "id": "<same id>", "ok": true, "value": { ... } }
59
49
  { "type": "result", "id": "<same id>", "ok": false, "error": "<human message>" }
60
50
 
61
51
  Unknown `name` MUST answer `ok:false`, never silence. The server times a
62
- command out after 5 s and treats it as failed, except `load_motion` and
63
- `import_asset`, which retain a dedicated 30 s editor bound (decode and stand a
64
- mesh, or install a take). Measurement
65
- justifies the existing headroom: 12 real editor installs of one 94,672-byte
66
- ARDY NPZ had nearest-rank p50 29.96 ms, p95 547.29 ms, and p99 547.29 ms;
67
- 30 s remains appropriate for materially larger cold-cache production takes. A timeout or disconnect during
52
+ command out after 5 s and treats it as failed, except `import_asset` and the
53
+ Studio commands (`inspect_studio`, `run_action`, `capture_framing_png`, ...),
54
+ which retain a dedicated 30 s editor bound. A timeout or disconnect during
68
55
  a mutation is ambiguous: it may already have applied, so callers MUST NOT retry
69
56
  blindly and should `describe` before recovering.
70
57
 
@@ -113,29 +100,6 @@ can wait for an editor instead of polling:
113
100
 
114
101
  { "type": "event", "name": "editor_connected" | "editor_disconnected", "payload": { "handle", "workspaceId", "meta" } }
115
102
 
116
- ## Motion jobs
117
-
118
- `generate_motion` returns immediately with exactly `{ taskId, status, createdAt,
119
- lastUpdatedAt, ttlMs, pollIntervalMs }`; `pollIntervalMs` is `0` because the
120
- model never polls it. The MCP server retains terminal outcomes for `ttlMs`
121
- (currently 10 minutes) and pushes `motion_job` to the matching stable workspace
122
- on completion, failure, cancellation, or reconnect. For a completed job, the
123
- server first installs the take through the request/response `load_motion`
124
- command, then publishes the terminal lifecycle event. The event never installs
125
- the take a second time. A retained outcome that passes its TTL is explicitly
126
- expired and is never replayed.
127
-
128
- If the editor explicitly rejects `load_motion`, the job transitions to `failed`
129
- and publishes that terminal event. If the socket disconnects or times out while
130
- installation is in flight, the job also fails but is not retried: the mutation
131
- may already have applied, so retrying could install the same take twice.
132
-
133
- Cancellation is cooperative at the bridge HTTP stream: `motion_job_cancel`
134
- aborts that request. The ARDY bridge detects the disconnected stream and kills
135
- its request-owned child process groups. A cancelled job is terminal and is never
136
- sent to editor installation. There are no `tasks/*` tools or start/status/list
137
- polling tools in the MCP surface.
138
-
139
103
  ## Commands (v1)
140
104
 
141
105
  All coordinates are metres, rotations are degrees of yaw, ids are the ids the
@@ -158,8 +122,6 @@ scene document already uses.
158
122
  | `group_objects` | `{ parent, children }` | `{ parent, children }` | attach every child under parent |
159
123
  | `ungroup_objects` | `{ children }` | `{ children }` | detach every child |
160
124
  | `apply_batch` | `{ ops, atomic?: false, stopOnError?: true, label?: "MCP batch" }` | `{ label, applied: number[], failed: [{ index, error }], rolledBack }` | executes at most 100 object mutations as one undo entry. `atomic` and `stopOnError` are independent; atomic failure restores the pre-batch objects and creates no undo entry. Nested batches are rejected. v1 rejects character mutations because cast history is a separate store. |
161
- | `set_prompt_blocks` | `{ blocks: [{ startFrame, endFrame, text }] }` | `{ blocks }` | replace the active character's authored prompt clips after validating each frame range and text |
162
- | `load_motion` | `{ url, prompt?, blocks?, drop? }` | `{ loaded, url, blocks }` | install an ARDY motion on the selected character. It has the dedicated 30-second editor-processing timeout; motion-job completion carries the character id captured when generation started |
163
125
  | `load_scenes` | `{ document }` | `{ sceneName, activeSceneId, scenes: [{ id, name }] }` | replace the whole scene document (same shape `serializeSceneDocument` emits); the response attests the full scene list and active scene for `add_scene` and `switch_scene` parity |
164
126
 
165
127
  ### Previs mode and character kind in the Studio context
@@ -176,12 +138,10 @@ is admitted against. Two parts of it describe what a project and its cast can do
176
138
 
177
139
  Before an animation-only tool runs, the server reads these fields from the
178
140
  context it admits the command against (`mark_camera_move`, which sends no
179
- command, reads `previsMode` from `describe`). In a storyboard project `generate_motion`, `set_prompt_blocks`, `load_motion` and
180
- `mark_camera_move` answer `{ ok: false, code: "NOT_IN_MODE", reason }` and send
181
- no command; `generate_motion` and `load_motion` on a capsule figure answer
182
- `{ ok: false, code: "TARGET_NOT_READY", reason }` with the kind's reason. The
183
- editor's own motion, take, IK and pose commands refuse a capsule figure with
184
- `TARGET_NOT_READY` as well, so `studio_run` reaches the same answer.
141
+ command, reads `previsMode` from `describe`). In a storyboard project
142
+ `mark_camera_move` answers `{ ok: false, code: "NOT_IN_MODE", reason }` and sends
143
+ no command. The editor's own motion, take, IK and pose commands refuse a capsule
144
+ figure with `TARGET_NOT_READY`, so `studio_run` reaches that answer.
185
145
 
186
146
  ## Hard rules for the editor side
187
147
 
package/mcp/README.md CHANGED
@@ -1,16 +1,16 @@
1
1
  # CozyClay MCP server
2
2
 
3
3
  Lets an AI assistant (Claude Desktop, Cursor, any MCP client) block a scene, place the camera,
4
- generate character motion and read the shot back as film vocabulary — then turn it into an AI
4
+ compile character motion and read the shot back as film vocabulary — then turn it into an AI
5
5
  image/video prompt.
6
6
 
7
7
  Works two ways, with one tool catalog:
8
8
 
9
- - **Editor open** — tool calls drive the visible viewport live: camera, cast, set, motion,
10
- prompt blocks on the timeline.
9
+ - **Editor open** — tool calls drive the visible viewport live: camera, cast, set and the
10
+ compiled motion on the timeline (`studio_run` with `motion.compile`).
11
11
  - **No editor** — scene, camera, prompt and project-file tools run in memory with no browser,
12
- GPU or build step. `capture_frame`, `set_prompt_blocks`, `generate_motion`, `apply_batch`,
13
- and `import_mesh` explicitly require a live editor.
12
+ GPU or build step. `capture_frame`, `apply_batch` and `import_mesh` explicitly require a
13
+ live editor.
14
14
 
15
15
  ## Run it locally
16
16
 
@@ -77,7 +77,6 @@ generated frame matches the blocking instead of drifting off into a generic shot
77
77
  | `group_objects` | attach children to a parent so they move as one; pass `parent: null` to detach |
78
78
  | `apply_batch` | execute up to 100 object mutations as one user-visible undo transaction |
79
79
  | `render_prompt` | the shot as an AI image or video prompt |
80
- | `generate_motion` | multi-phase character motion through the ARDY bridge — phases land as prompt blocks |
81
80
  | `mark_camera_move` / `describe_camera_move` | name a move between two camera positions |
82
81
  | `add_scene` / `switch_scene` | multiple scenes per project |
83
82
  | `open_project` / `save_project` | read and write `.cclayproject` files |
@@ -116,38 +115,29 @@ thin terminal front end over this hub, not a parallel surface, so anything true
116
115
  above (admission envelopes, receipts, per-workspace exclusion) is true of it too. The
117
116
  terminal-agent guide for it is [`../docs/agent-cli.md`](../docs/agent-cli.md).
118
117
 
119
- ## Motion generation
118
+ ## Motion
120
119
 
121
- `generate_motion` takes plain-language beats and a length:
122
-
123
- ```
124
- phases: ["seated on a chair, slowly stands up",
125
- "breaks into a sprint",
126
- "trips and falls hard to the ground"]
127
- seconds: 10
128
- ```
129
-
130
- It tiles them into contiguous ARDY segments, streams the generation through the local bridge
131
- (`127.0.0.1:5181`, started by `npm run dev`), and — when an editor is connected — loads the
132
- result onto the active character with prompt blocks on the timeline. Beats longer than the
133
- per-block limit are split into consecutive blocks, so one phase can produce multiple blocks.
134
- Pass a previous `motion_url` to reload a clip without generating again.
120
+ Motion is compiled, not generated: run `motion.compile` through `studio_run` with a motion
121
+ spec (key poses, anchors, props, walks, hinged objects, task checks). The Studio bakes every
122
+ frame on the rig, answers the QA groups, and installs the take; `motion.sample` and
123
+ `motion.qa` read it back. The spec format and the loop are in
124
+ [`../docs/motion3-agent-guide.md`](../docs/motion3-agent-guide.md).
135
125
 
136
126
  ## Storyboard projects and capsule figures
137
127
 
138
- The tool list is fixed when the server starts, so it is the same 28 tools in every project. A
128
+ The tool list is fixed when the server starts, so it is the same 27 tools in every project. A
139
129
  tool that does not apply to the project or to its target answers a structured refusal instead
140
130
  of acting; nothing is sent to the editor and nothing changes. The refusal is the tool's only
141
131
  text content, with `isError: true`:
142
132
 
143
133
  ```json
144
- { "ok": false, "code": "NOT_IN_MODE", "reason": "This project is a Storyboard - generate_motion is available in Animation projects." }
134
+ { "ok": false, "code": "NOT_IN_MODE", "reason": "This project is a Storyboard - mark_camera_move is available in Animation projects." }
145
135
  ```
146
136
 
147
137
  | code | when | tools |
148
138
  | --- | --- | --- |
149
- | `NOT_IN_MODE` | the project's `previsMode` is `storyboard` | `generate_motion`, `set_prompt_blocks`, `load_motion`, `mark_camera_move` |
150
- | `TARGET_NOT_READY` | the target character is a capsule figure (`model: "proxy-figure"`) | `generate_motion` (the editor's active character), `load_motion` (its `character`, else the active one) |
139
+ | `NOT_IN_MODE` | the project's `previsMode` is `storyboard` | `mark_camera_move` |
140
+ | `TARGET_NOT_READY` | the target character is a capsule figure (`model: "proxy-figure"`) | `studio_run` motion, take, IK and pose actions |
151
141
 
152
142
  `describe_scene` reports `previsMode: storyboard` or `previsMode: animation` (the connected
153
143
  editor's project; `open_project` sets it without one) and marks each cast member
@@ -156,7 +146,7 @@ editor's project; `open_project` sets it without one) and marks each cast member
156
146
  A **storyboard project** is a sequence of still shots: one picture per panel, held for a
157
147
  number of frames, with a caption. Block it with the camera, cast and set tools, and run the
158
148
  still-shot commands (`shot.createStill`, `shot.setCaption`, `shot.setHold`, ...) through
159
- `studio_run`. Motion, prompt blocks and named camera moves belong to Animation projects.
149
+ `studio_run`. Motion and named camera moves belong to Animation projects.
160
150
 
161
151
  A **capsule figure** is a rigless stand-in for blocking: `add_character { subject, model:
162
152
  "proxy-figure", posture: "sit" }`. It places, turns and frames like any cast member and holds a
package/mcp/live-hub.mjs CHANGED
@@ -11,7 +11,7 @@ export const DEFAULT_COMMAND_TIMEOUT_MS = 5_000;
11
11
  export const MAX_COMMAND_TIMEOUT_MS = 300_000;
12
12
  export const DEFAULT_HEARTBEAT_MS = 15_000;
13
13
  export const RUN_WORKFLOW_TIMEOUT_MS = 180_000;
14
- export const LOAD_MOTION_TIMEOUT_MS = 30_000;
14
+
15
15
  export const IMPORT_ASSET_TIMEOUT_MS = 30_000;
16
16
  export const CAPTURE_FRAME_TIMEOUT_MS = 30_000;
17
17
  export const STUDIO_COMMAND_TIMEOUT_MS = 30_000;
@@ -31,9 +31,7 @@ const mutationCommands = new Set([
31
31
  "remove_object",
32
32
  "group_objects",
33
33
  "ungroup_objects",
34
- "apply_batch",
35
- "set_prompt_blocks",
36
- "load_motion",
34
+ "apply_batch",
37
35
  "load_scenes",
38
36
  "operate_studio", "arrange_objects", "arrange_characters", "patch_elements", "frame_shot", "undo_edit", "run_action",
39
37
  "import_asset",
@@ -75,7 +73,7 @@ const safely = (work) => {
75
73
  const mutationState = (name, description) => {
76
74
  if (!description || typeof description !== "object") return undefined;
77
75
  if (name === "set_camera") return description.camera;
78
- if (["add_character", "update_character", "remove_character", "set_prompt_blocks"].includes(name)) return description.characters;
76
+ if (["add_character", "update_character", "remove_character"].includes(name)) return description.characters;
79
77
  if (name === "load_scenes") return description.document;
80
78
  return description.objects;
81
79
  };
@@ -138,7 +136,7 @@ export class LiveHub {
138
136
  }
139
137
 
140
138
  static commandTimeoutMs(name) {
141
- if (name === "load_motion") return LOAD_MOTION_TIMEOUT_MS;
139
+
142
140
  // A 32 MiB mesh as a data URL will not decode, store and stand in 5 s.
143
141
  if (name === "import_asset") return IMPORT_ASSET_TIMEOUT_MS;
144
142
  // Close two-person shots (OTS) raycast two skinned rigs over a full-frame
@@ -216,7 +214,7 @@ export class LiveHub {
216
214
  const observer = {
217
215
  hub: this, handle,
218
216
  before(command) {
219
- if (!LiveHub.commandMayMutate(command) || command === "load_motion" || command === "run_action") return false;
217
+ if (!LiveHub.commandMayMutate(command) || command === "run_action") return false;
220
218
  mutation = { name: command, before: mutationState(command, description), acknowledged: false };
221
219
  description = undefined;
222
220
  return mutation.before === undefined;
@@ -253,9 +251,7 @@ export class LiveHub {
253
251
  if (mutation) mutation.rolledBack = value?.rolledBack === true;
254
252
  if (value?.rolledBack === true || value?.failed?.length > 0) failure = "failed";
255
253
  }
256
- // The load acknowledgement is the existing installation receipt,
257
- // including generation jobs whose MCP control response was queued.
258
- if (command === "load_motion" && value?.loaded === true) applied = true;
254
+
259
255
  }
260
256
  emitApplied();
261
257
  },
package/mcp/package.json CHANGED
@@ -11,10 +11,8 @@
11
11
  "start": "node server.mjs",
12
12
  "verify": "node verify.mjs && node verify-protocol-version.mjs && node verify-http-origin.mjs && node verify-import-mesh.mjs",
13
13
  "verify:annotations": "node verify-tool-annotations.mjs",
14
- "verify:prompts": "node verify-prompts.mjs",
15
14
  "verify:live": "node verify-live.mjs && node verify-live-p0.mjs && node verify-live-routing.mjs && node verify-live-controller.mjs && node verify-live-scene-parity.mjs && node verify-live-batch.mjs && node verify-live-editor-model.mjs && node verify-live-port.mjs",
16
- "verify:capture": "node verify-live-capture.mjs",
17
- "verify:motion-job": "node verify-live-motion-job.mjs"
15
+ "verify:capture": "node verify-live-capture.mjs"
18
16
  },
19
17
  "engines": {
20
18
  "node": ">=22.13"
@@ -33,8 +33,6 @@ import { readMeshFromPath } from "./mesh-file.mjs";
33
33
  import { encodePng, readImageFromPath } from "./image-file.mjs";
34
34
  import { rankingRow, scoreSculptAgainstReference } from "../src/sculpt-compare.js";
35
35
  import { DEFAULT_POSE } from "../src/poses.js";
36
- import { generationArgs } from '../src/motion/generation.js';
37
- import { BLOCK_MAX_SECONDS, PROMPT_GUIDE, normalizePhases, splitLongBeat, tileClipFrames } from "./ardy-prompts.mjs";
38
36
 
39
37
  import {
40
38
  CAMERA_MOVES,
@@ -105,8 +103,8 @@ export const liveWorkspace = new AsyncLocalStorage();
105
103
  const liveWorkspaceTools = new Set([
106
104
  "describe_scene", "describe_shot", "render_prompt", "mark_camera_move", "describe_camera_move", "save_project",
107
105
  "set_camera", "frame_shot", "add_character", "place_character", "remove_character",
108
- "focus_character", "place_object", "import_mesh", "sculpt_object", "compare_sculpt", "group_objects", "set_prompt_blocks", "generate_motion", "update_object",
109
- "remove_object", "apply_batch", "add_scene", "switch_scene", "open_project", "capture_frame", "load_motion",
106
+ "focus_character", "place_object", "import_mesh", "sculpt_object", "compare_sculpt", "group_objects", "update_object",
107
+ "remove_object", "apply_batch", "add_scene", "switch_scene", "open_project", "capture_frame",
110
108
  "studio_commands", "studio_run",
111
109
  ]);
112
110
  const MAX_CAPTURE_BYTES = 1_000_000;
@@ -114,7 +112,6 @@ const CAPTURE_ARTIFACT_TTL_MS = 10 * 60_000;
114
112
  const MAX_CAPTURE_ARTIFACTS = 20;
115
113
  const captureArtifacts = [];
116
114
  const captureArtifactPattern = /^cozyclay-capture-[0-9a-f-]+\.png$/;
117
- const motionUrlPattern = /^\/(ardy\/motions\/[0-9]+-[0-9a-f]{6}|ardy\/assembled\/[A-Za-z0-9._-]+\.npz)$/;
118
115
  export const cleanupCaptureArtifacts = () => {
119
116
  for (const path of captureArtifacts.splice(0)) {
120
117
  try { unlinkSync(path); } catch {}
@@ -164,9 +161,6 @@ const TOOL_ANNOTATIONS = Object.freeze({
164
161
  sculpt_object: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
165
162
  compare_sculpt: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
166
163
  group_objects: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
167
- set_prompt_blocks: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
168
- load_motion: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
169
- generate_motion: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
170
164
  update_object: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
171
165
  remove_object: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },
172
166
  apply_batch: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },
@@ -242,8 +236,6 @@ const previsRefusal = (toolName, { feature, context, characterId } = {}) => {
242
236
  : isProxyFigure(findCharacter(characterId ?? state.focus));
243
237
  return proxy ? refusal("TARGET_NOT_READY", kindRefusal(feature)) : null;
244
238
  };
245
- /** The Studio context and one command's declaration, as executeStudioCommand admits it. */
246
- const inspectAction = (action) => liveHub.command("inspect_studio", { scope: "actions", ids: [action] }, liveWorkspace.getStore());
247
239
 
248
240
  const scene = () => activeScene(state.doc.scenes, state.doc.activeSceneId);
249
241
  const stage = () => scene().stage;
@@ -514,8 +506,7 @@ function sceneReport({ characterCursor = 0, objectCursor = 0, limit = 50 } = {})
514
506
  `${c.pose ? " posed" : ""}${c.hidden ? " hidden" : ""}` +
515
507
  `${c === framed ? " <- framed" : ""}`,
516
508
  ` model: ${c.model} kind: ${isProxyFigure(c) ? "proxy" : "rig"}${isProxyFigure(c) ? ` posture: ${c.posture ?? "stand"}` : ""} pose: ${JSON.stringify(c.pose ?? null)} tint: ${c.tint ?? null} scale: ${c.scale ?? 1}`,
517
- ` motionRef: ${JSON.stringify(c.motionRef ?? null)}`,
518
- ` layer: ${JSON.stringify({ waypoints: c.layer?.waypoints ?? [], promptClips: c.layer?.promptClips ?? [] })}`,
509
+ ` layer: ${JSON.stringify({ waypoints: c.layer?.waypoints ?? [] })}`,
519
510
  );
520
511
  }
521
512
 
@@ -589,7 +580,7 @@ function shotReport() {
589
580
  const studioAliasTools = new Set([
590
581
  "set_camera", "frame_shot", "place_object", "update_object", "remove_object",
591
582
  "import_mesh", "sculpt_object", "group_objects", "add_scene", "switch_scene", "apply_batch", "open_project",
592
- "add_character", "place_character", "remove_character", "set_prompt_blocks", "load_motion", "generate_motion",
583
+ "add_character", "place_character", "remove_character",
593
584
  ]);
594
585
  const studioAdmissionSchema = {
595
586
  expectedRevision: z.number().int().min(0).optional().describe("scene revision to admit against; defaults to the inspected revision"),
@@ -1319,161 +1310,6 @@ export const createToolHandlers = ({ projectRootPromise } = {}) => {
1319
1310
  },
1320
1311
  ),
1321
1312
 
1322
- tool(
1323
- "set_prompt_blocks",
1324
- {
1325
- title: "Author the motion beats on the timeline",
1326
- description:
1327
- "Write Prompt Blocks onto the timeline WITHOUT generating — the beats and their frame " +
1328
- "ranges, so a schedule can be read and revised before any GPU time is spent. Hit " +
1329
- "the studio's top-bar Generate Motion button, or call generate_motion, when it reads right.\n\n" +
1330
- PROMPT_GUIDE,
1331
- inputSchema: {
1332
- beats: z
1333
- .array(
1334
- z.object({
1335
- text: z.string().min(3).describe("the beat, in ARDY's sentence shape"),
1336
- seconds: z
1337
- .number()
1338
- .min(0.5)
1339
- .max(20)
1340
- .optional()
1341
- .describe(`how long this beat holds; defaults to 3 s when omitted, and over ${BLOCK_MAX_SECONDS}s it becomes chained blocks`),
1342
- }),
1343
- )
1344
- .min(1)
1345
- .max(8)
1346
- .describe("beats in order; each one becomes a contiguous block"),
1347
- },
1348
- },
1349
- async ({ beats, ...admission }) => {
1350
- if (!liveHub?.connected) {
1351
- return previsRefusal("set_prompt_blocks") ?? text("Prompt Blocks live on the studio timeline — open the editor and try again.");
1352
- }
1353
- const normalized = normalizePhases(beats.map((b) => b.text));
1354
- // The timeline runs on a 24 fps production clock.
1355
- const TIMELINE_FPS = 24;
1356
- let cursor = 0;
1357
- const blocks = [];
1358
- for (const [i, textValue] of normalized.texts.entries()) {
1359
- const whole = beats[Math.min(normalized.sources[i], beats.length - 1)].seconds ?? 3;
1360
- const spans = splitLongBeat(whole);
1361
- for (const span of spans) {
1362
- const frames = Math.max(1, Math.round(span * TIMELINE_FPS));
1363
- blocks.push({ startFrame: cursor, endFrame: cursor + frames, text: textValue });
1364
- cursor += frames;
1365
- }
1366
- }
1367
- try {
1368
- const inspected = await inspectAction("character.setPromptBlocks");
1369
- return previsRefusal("set_prompt_blocks", { context: await contextOf(inspected) }) ??
1370
- await runStudioCommand({ ...admission, inspected, action: "character.setPromptBlocks", args: context => ({
1371
- characterId: context.activeCharacterId, blocks,
1372
- }) });
1373
- } catch (error) {
1374
- return liveError(error);
1375
- }
1376
- },
1377
- ),
1378
-
1379
- tool(
1380
- "load_motion",
1381
- {
1382
- title: "Load an existing motion take",
1383
- description:
1384
- "Unlike generate_motion, load_motion installs a previously generated or assembled motion take WITHOUT regenerating — " +
1385
- "re-using a completed /ardy/motions/<id> take or an /ardy/assembled/*.npz tile (the long-take recipe). " +
1386
- "It is synchronous and returns the editor's confirmation.",
1387
- inputSchema: {
1388
- url: z.string().describe("/ardy/motions/<id> or /ardy/assembled/<name>.npz"),
1389
- prompt: z.string().optional().describe("Label shown on the timeline block."),
1390
- character: z.string().optional().describe('which character receives the take — letter, slot number or id; defaults to the editor\u2019s active character'),
1391
- },
1392
- },
1393
- async (args) => {
1394
- if (!motionUrlPattern.test(args.url)) {
1395
- throw new Error(`Unsupported motion url "${args.url}". Use /ardy/motions/<id> or /ardy/assembled/<name>.npz.`);
1396
- }
1397
- const inspected = liveHub?.connected ? await inspectAction('motion.replace') : undefined;
1398
- const characterId = args.character === undefined ? inspected?.context?.activeCharacterId : await liveCharacterId(args.character);
1399
- const refused = previsRefusal("load_motion", { feature: "take", context: await contextOf(inspected), characterId });
1400
- if (refused) return refused;
1401
- return runStudioCommand({ ...args, inspected, action: 'motion.replace', args: context => ({
1402
- characterId: args.character === undefined ? context.activeCharacterId : characterId,
1403
- url: args.url, prompt: args.prompt ?? '',
1404
- }) });
1405
- },
1406
- ),
1407
-
1408
- tool(
1409
- "generate_motion",
1410
- {
1411
- title: "Generate character motion (Kimodo)",
1412
- description:
1413
- "Alias for motion.generate in the editor. Returns its bus receipt; started jobs carry jobId for studio_run job.await or job.cancel. " +
1414
- "The installed take is undoable with studio_run edit.undo.\n\n" +
1415
- PROMPT_GUIDE,
1416
- inputSchema: {
1417
- phases: z
1418
- .array(
1419
- z.union([
1420
- z.string().min(3),
1421
- z.object({
1422
- text: z.string().min(3),
1423
- seconds: z.number().min(0.5).max(30).describe("how long THIS beat holds"),
1424
- }),
1425
- ]),
1426
- )
1427
- .min(1)
1428
- .max(8)
1429
- .describe(
1430
- "one beat per phase, in order. Follow the shared Kimodo prompt guide in this tool's " +
1431
- "description; it is the single source for prompt wording and phase guidance. Give a " +
1432
- "plain string to share the clip evenly, or { text, seconds } to hold a beat for a " +
1433
- "specific time.",
1434
- ),
1435
- seconds: z
1436
- .number()
1437
- .min(2)
1438
- .max(60)
1439
- .default(9)
1440
- .describe("total clip length; ignored when every phase carries its own seconds"),
1441
- seed: z.number().int().optional().describe("generation seed"),
1442
- motion_url: z
1443
- .string()
1444
- .regex(motionUrlPattern)
1445
- .optional()
1446
- .describe("reuse an already-generated clip, or a curated clip staged under public/ardy/assembled/"),
1447
- drop: z
1448
- .object({
1449
- from_s: z.number().min(0).describe("clip time the plunge begins, seconds"),
1450
- to_s: z.number().positive().describe("clip time it lands, seconds; must be after from_s"),
1451
- meters: z.number().positive().max(30).describe("how far the body falls"),
1452
- })
1453
- .optional()
1454
- .describe(
1455
- "a vertical fall staged onto the clip — the whole body drops this many metres over " +
1456
- "[from_s, to_s] on a gravity curve. Stand the character on a roof with place_character's " +
1457
- "y, then drop them past its edge; ARDY itself only generates flat-ground motion.",
1458
- ),
1459
- },
1460
- },
1461
- async ({ phases, seconds = 9, seed, motion_url, drop, ...admission }) => {
1462
- if (!liveHub?.connected) return previsRefusal("generate_motion", { feature: "motion" }) ?? text(noLiveEditor("Motion requires a connected CozyClay editor."));
1463
- const normalized = normalizePhases(phases.map(phase => typeof phase === 'string' ? phase : phase.text));
1464
- const beats = normalized.texts.map((text, index) => ({ text, seconds: phases[normalized.sources[index]]?.seconds ?? seconds / phases.length })).filter(beat => beat.text);
1465
- const action = motion_url ? 'motion.replace' : 'motion.generate', inspected = await inspectAction(action);
1466
- const refused = previsRefusal("generate_motion", { feature: "motion", context: await contextOf(inspected) });
1467
- if (refused) return refused;
1468
- return runStudioCommand({ ...admission, inspected, action, args: context => {
1469
- const generated = generationArgs({ characterId: context.activeCharacterId, source: { kind: 'generate', beats, ...(seed === undefined ? {} : { seed }) } });
1470
- return motion_url ? { characterId: generated.characterId, url: motion_url, prompt: beats.map(beat => beat.text).join(' '),
1471
- blocks: generated.blocks.map(({ startFrame, endFrame, text: prompt }) => ({ startFrame, endFrame, prompt })), ...(drop ? { drop } : {}) }
1472
- : { ...generated, ...(drop ? { drop } : {}) };
1473
- } });
1474
- },
1475
- ),
1476
-
1477
1313
  tool(
1478
1314
  "update_object",
1479
1315
  {