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,4 +1,4 @@
1
- import { copyPhysicsKeys } from "../ardy/physics-review.js";
1
+ import { copyPhysicsKeys } from "../motion/physics-review.js";
2
2
  import { useState, useMemo, useEffect, useSyncExternalStore, useContext } from "react";
3
3
  import { AppContext } from '../app-context.js';
4
4
  import { createDocumentStore } from "../document-store.js";
@@ -13,32 +13,25 @@ import {
13
13
  saveCustomPoses,
14
14
  } from "../poses.js";
15
15
  import { createCharacterEntry, createCharacterLayer, isProxyFigure, PROXY_FIGURE_MODEL } from "../scenes.js";
16
- import { kindRefusal } from "../character-kind.js";
17
16
  import {
18
17
  DEFAULT_SUBJECT,
19
18
  DEFAULT_SUBJECT2,
20
19
  nextCharacterId,
21
20
  MAX_WAYPOINTS,
22
- MULTIMODEL_REASONS,
23
- ARDY_DURATION_MIN,
24
- TIMELINE_FPS,
25
21
  } from "../app-stage.jsx";
26
22
  import { ko, isKo } from "../locale.js";
27
- import { createIkState } from "../ardy/ik.js";
28
- import { judgeNextWaypoint } from "../ardy/waypoints.js";
23
+ import { createIkState } from "../motion/ik.js";
24
+ import { judgeNextWaypoint } from "../motion/waypoints.js";
29
25
  import { StudioProtocolError } from "../studio-agent-protocol.js";
30
26
  import { studioActionRefusal } from "../studio-actions.js";
31
27
  import { createStableItemId, removeStableItem } from "../stable-items.js";
32
28
  import { track, trackFeature } from "../analytics.js";
33
- import { requestBridgeExtract } from "../multimodel-ingest.js";
34
- import { loadMotionFromUrl } from "../ardy/npz.js";
35
- import { snapshotPlaybackBones, applyMotionFrame, restorePlaybackBones } from "../ardy/playback.js";
36
29
 
37
30
  import { shotAtFrame } from "../cuts.js";
38
31
 
39
32
  const sameCastValue = (a, b) => JSON.stringify(a) === JSON.stringify(b);
40
33
 
41
- export function createCastDomain(appContext, initial, customPoses = []) {
34
+ function createCastDomain(appContext, initial, customPoses = []) {
42
35
  const normalize = value => ({ characters: (Array.isArray(value) ? value : value.characters).map(createCharacterEntry),
43
36
  customPoses: Array.isArray(value) ? customPoses : value.customPoses ?? customPoses });
44
37
  let native = createDocumentStore({ owned: { cast: normalize(initial) } });
@@ -329,7 +322,6 @@ export function useCast(appContext) {
329
322
  // every playhead tick.
330
323
  const ghostLayers = useMemo(() => characters.flatMap((entry, index) => entry.id === activeChar.id || entry.hidden ? [] : [{
331
324
  owner: `S${index + 1}`,
332
- promptClips: entry.layer?.promptClips ?? [],
333
325
  waypointFrames: (entry.layer?.waypoints ?? []).map((waypoint) => waypoint.frame),
334
326
  }]), [characters, activeChar.id]);
335
327
 
@@ -340,7 +332,7 @@ export function useCast(appContext) {
340
332
  characters: appContext.live.characters.map((entry) => ({
341
333
  ...entry,
342
334
  layer: entry.id === activeChar.id
343
- ? { waypoints: appContext.shared.bufferRef.current.waypoints, promptClips: appContext.shared.bufferRef.current.promptClips }
335
+ ? { waypoints: appContext.shared.bufferRef.current.waypoints }
344
336
  : entry.layer,
345
337
  })),
346
338
  bufferMotion: appContext.shared.bufferRef.current.motion,
@@ -365,11 +357,7 @@ export function useCast(appContext) {
365
357
 
366
358
  const [hasCharSheet, setHasCharSheet] = useState(appContext.shared.startupStage.hasCharSheet);
367
359
 
368
- // Bumped when something outside the Inspector needs the Prompt Blocks panel
369
- // on screen — selecting or adding a block on the timeline.
370
- const [promptBlocksReveal, setPromptBlocksReveal] = useState(0);
371
-
372
- const revealPromptBlocks = () => setPromptBlocksReveal((n) => n + 1);
360
+
373
361
 
374
362
  // Root waypoints {frame, x, z, heading: null}, kept sorted by frame —
375
363
  // the fixed bridge contract rejects out-of-order or duplicate frames.
@@ -382,13 +370,6 @@ export function useCast(appContext) {
382
370
 
383
371
  const [pendingWaypointFrame, setPendingWaypointFrame] = useState(null);
384
372
 
385
- const promptClips = activeChar.layer.promptClips;
386
- const setPromptClips = value => setLayerField('promptClips', value);
387
- const editPromptClips = value => writeLayerField(domain.activeId, 'promptClips', value);
388
- function writeLayerField(characterId, key, value) {
389
- domain.write(rows => rows.map(entry => entry.id === characterId ? { ...entry, layer: { ...entry.layer,
390
- [key]: typeof value === 'function' ? value(entry.layer[key]) : value } } : entry));
391
- }
392
373
  function setLayerField(key, value) {
393
374
  const entry = domain.read().find(entry => entry.id === domain.activeId) ?? domain.read()[0];
394
375
  const next = typeof value === 'function' ? value(entry.layer[key]) : value;
@@ -396,11 +377,7 @@ export function useCast(appContext) {
396
377
  return domain.run('cast.setLayer', { characterId: entry.id, layer: { [key]: next } });
397
378
  }
398
379
 
399
- const [selectedPromptId, setSelectedPromptId] = useState(null);
400
-
401
- const [photoPoseState, setPhotoPoseState] = useState("idle");
402
-
403
- const [photoPoseError, setPhotoPoseError] = useState("");
380
+
404
381
 
405
382
  // The library is the user's own material: poses read from photographs and
406
383
  // poses saved off the rig, accumulating across sessions and projects. No
@@ -625,7 +602,6 @@ export function useCast(appContext) {
625
602
  const next = !waypointMode;
626
603
  // Both modes want the viewport pointer; the last one switched on wins,
627
604
  // the other stands down rather than fighting for pointerdown.
628
- if (next && appContext.shared.lineEditMode) appContext.shared.exitLineEditMode();
629
605
  setWaypointMode(next);
630
606
  if (!next) {
631
607
  setPendingWaypointFrame(null);
@@ -711,143 +687,13 @@ export function useCast(appContext) {
711
687
  appContext.notify(ko("Pose saved", "포즈 저장됨"));
712
688
  }
713
689
 
714
- /**
715
- * Read a body pose out of one photograph.
716
- *
717
- * A still is the degenerate footage case, so it walks the same proven path:
718
- * landmarks -> one-frame take -> applyMotionFrame -> capturePose. Posing the
719
- * rig and reading it back is what makes the result an ordinary editable pose
720
- * rather than a motion layer — the IK handles keep working on it, and the
721
- * playback bones are restored so nothing about the take survives the read.
722
- *
723
- * Depth in a single frame is inferred, not measured, so this is a starting
724
- * pose to refine, which is why it lands in the studio instead of on the
725
- * character directly.
726
- */
727
- async function posePhotoFile(file) {
728
- if (!file || photoPoseState === "running") return;
729
- // Reachable from the Inspector as well as the studio panel, and posedRig()
730
- // only answers while the studio is open — fall back to the character the
731
- // hierarchy has selected, which is the one the pose will be applied to.
732
- const rig = posedRig() ?? activeRig;
733
- let objectUrl = "";
734
- setPhotoPoseState("running");
735
- setPhotoPoseError("");
736
- try {
737
- // A capsule figure has no bones for a photo to pose.
738
- if (isProxyFigure(posingChar ?? activeChar)) throw new StudioProtocolError("TARGET_NOT_READY", kindRefusal("photoPose", isKo));
739
- if (!rig) throw new Error("rig-not-loaded");
740
- objectUrl = URL.createObjectURL(file);
741
- let bones = null;
742
- let rootY = 0;
743
- let gpuError = null;
744
- // GVHMR on the box measures the body over the whole clip,
745
- // which is more reliable than a single-frame depth estimate.
746
- // The bridge wraps the still into a second of video and runs the exact
747
- // GVHMR footage pipeline. A missing bridge or another backend is an error.
748
- try {
749
- const health = await fetch("/ardy/health", { signal: AbortSignal.timeout(2000) }).catch(() => null);
750
- if (!health?.ok) throw new Error("extract-bridge-required");
751
- const healthPayload = await health.json().catch(() => null);
752
- if (healthPayload?.extractionBackend !== "gvhmr") throw new Error("extract-backend-unsupported");
753
- const done = await requestBridgeExtract(file, {});
754
- const take = await loadMotionFromUrl(done.motionUrl);
755
- // The middle frame: the wrap's smoothing passes have settled
756
- // there, while frame 0 can still carry filter warm-up.
757
- const frame = Math.floor((take.frames - 1) / 2);
758
- const snapshot = snapshotPlaybackBones(rig);
759
- try {
760
- applyMotionFrame(rig, { ...take, anchorFrame: frame }, frame);
761
- bones = capturePose(rig);
762
- // GVHMR measured the hips' true height — a crouch is a crouch
763
- // because the hips came DOWN, not just because the knees bent.
764
- rootY = captureHipsOffset(rig);
765
- } finally {
766
- restorePlaybackBones(rig, snapshot);
767
- }
768
- } catch (error) {
769
- gpuError = error;
770
- console.warn("photo pose: GVHMR extract failed", error);
771
- }
772
- if (!bones) throw new Error(gpuError?.message || "extract-run-failed");
773
- const pose = {
774
- id: `photo_${Date.now()}`,
775
- label: isKo ? `사진 포즈 ${customPoses.length + 1}` : `Photo Pose ${customPoses.length + 1}`,
776
- prompt: "in the exact body pose shown in the reference photograph",
777
- bones,
778
- rootY,
779
- custom: true,
780
- };
781
- setStudioPick(pose.id);
782
- // The studio poses whichever character it was opened on; the Inspector
783
- // poses the selected one. Write the pose to whichever that is.
784
- const poseTargetIndex = posingIndex >= 0 ? posingIndex : activeCharIndex;
785
- // A running take drives the same bones a pose writes, so the read would
786
- // land invisibly underneath it. Applying from a photo follows the same
787
- // rule the Apply button already states: the motion goes first.
788
- const hadMotion = Boolean(appContext.shared.motion);
789
- domain.run('cast.savePose', { pose, characterId: characters[poseTargetIndex].id, clearMotion: hadMotion });
790
- setPhotoPoseState("done");
791
- // The pose is already saved and written by this point. GVHMR either
792
- // returns a measured pose or the named error above reaches the user.
793
- appContext.notify(hadMotion
794
- ? ko("Cleared the motion and posed from the photo — refine it with the handles", "모션을 지우고 사진으로 자세를 잡았어요 — 핸들로 다듬어 보세요")
795
- : ko("Pose read from the photo — refine it with the handles", "사진에서 자세를 읽었어요 — 핸들로 다듬어 보세요"));
796
- } catch (error) {
797
- const code = error?.message ?? String(error);
798
- // fitLandmarksToPose refuses a sample whose torso is not visible; that is
799
- // a photograph problem, not an engine problem, so it is named as one.
800
- const named = code.startsWith("fitLandmarksToPose:") ? "pose-partly-occluded" : code;
801
- setPhotoPoseState("error");
802
- setPhotoPoseError(MULTIMODEL_REASONS[named]?.[isKo ? 1 : 0] ?? named);
803
- } finally {
804
- if (objectUrl) URL.revokeObjectURL(objectUrl);
805
- }
806
- }
807
-
808
690
  function removePose(id) {
809
691
  domain.run('cast.removePose', { id });
810
692
  if (studioPick === id) setStudioPick(DEFAULT_POSE.id);
811
693
  }
812
694
 
813
- function addPromptClip(frame, surface = "timeline") {
814
- const before = domain.read().find(entry => entry.id === domain.activeId).layer.promptClips;
815
- const receipt = domain.run('character.addPromptBlock', { characterId: domain.activeId, frame });
816
- const clip = domain.read().find(entry => entry.id === domain.activeId).layer.promptClips.find(clip => !before.some(row => row.id === clip.id));
817
- setSelectedPromptId(clip.id);
818
- appContext.shared.setArdyDuration(Math.max(ARDY_DURATION_MIN, clip.endFrame / TIMELINE_FPS));
819
- trackFeature('prompt_block_add'); return receipt;
820
- }
821
-
822
- function changePromptClip(id, text) {
823
- domain.beginGesture();
824
- const receipt = domain.edit('character.changePromptBlock', { characterId: domain.activeId, id, text });
825
- if (id === selectedPromptId) appContext.shared.setArdyPrompt(text);
826
- return receipt;
827
- }
828
-
829
- // Quality policy: one prompt block never spans more than 5 s. Kimodo
830
- // walk-to-run sweeps (seeds 7/21/99; seam stall ratio, 1.0 = no stall)
831
- // scored 0.79 for 5 s blocks (best of the sweep), close to a seam-free
832
- // single take at 0.85; 8 s blocks collapsed to 0.32. <2 s blocks lose
833
- // about a third of their frames to the transition window, so 3-5 s is the recommended
834
- // authoring range.
835
- const PROMPT_BLOCK_MAX_FRAMES = 5 * TIMELINE_FPS;
836
-
837
- function resizePromptClip(id, edge, frame) {
838
- return domain.edit('character.resizePromptBlock', { characterId: domain.activeId, id, edge, frame });
839
- }
840
- function movePromptClip(id, frame) {
841
- return domain.edit('character.movePromptBlock', { characterId: domain.activeId, id, frame });
842
- }
843
- function removePromptClip(id) {
844
- const receipt = domain.run('character.removePromptBlock', { characterId: domain.activeId, id });
845
- if (selectedPromptId === id) setSelectedPromptId(null);
846
- return receipt;
847
- }
848
695
  function applyExternalCharacters(characters) {
849
696
  appContext.storeDomain('cast').run('cast.replace', { characters });
850
- appContext.shared.restoreMotionRefs(characters);
851
697
  }
852
698
  function publishStudioCharacters(next) {
853
699
  if (typeof next === 'function') next = next(appContext.live.characters);
@@ -857,18 +703,15 @@ export function useCast(appContext) {
857
703
  for (const entry of next) if (Object.hasOwn(entry, 'sessionMotion')) owner.publishMotion(entry.id, entry.sessionMotion);
858
704
  }
859
705
  /** The active character's layer lives in the editing buffer, and the read
860
- * model folds that buffer back over the cast. A published or restored prompt
861
- * schedule or root path has to reach it in the same tick, or the next read
862
- * would revert it. */
706
+ * model folds that buffer back over the cast. A published or restored root
707
+ * path has to reach it in the same tick, or the next read would revert it. */
863
708
  function syncStudioLayerBuffer(rows) {
864
709
  if (appContext.storeDomain('cast')) return appContext.storeDomain('cast').syncLayer();
865
710
  const layer = rows.find(entry => entry.id === appContext.shared.loadedLayerCharRef.current)?.layer;
866
711
  const changed = key => Array.isArray(layer?.[key]) && JSON.stringify(layer[key]) !== JSON.stringify(appContext.shared.bufferRef.current[key]);
867
- const clips = changed("promptClips"), path = changed("waypoints");
868
- if (!clips && !path) return;
869
- appContext.shared.bufferRef.current = { ...appContext.shared.bufferRef.current, ...(clips ? { promptClips: layer.promptClips } : {}), ...(path ? { waypoints: layer.waypoints } : {}) };
870
- if (clips) setPromptClips(layer.promptClips);
871
- if (path) setWaypoints(layer.waypoints);
712
+ if (!changed("waypoints")) return;
713
+ appContext.shared.bufferRef.current = { ...appContext.shared.bufferRef.current, waypoints: layer.waypoints };
714
+ setWaypoints(layer.waypoints);
872
715
  }
873
716
  function undoScene() {
874
717
  const receipt = appContext.bus.run('edit.undo');
@@ -914,7 +757,7 @@ export function useCast(appContext) {
914
757
  switchNativeMotionLayer(previous, entry);
915
758
  appContext.shared.loadedLayerCharRef.current = entry.id;
916
759
  domain.syncLayer();
917
- setSelectedPromptId(null); setWaypointMode(false); setActiveWaypointId(null); setPendingWaypointFrame(null);
760
+ setWaypointMode(false); setActiveWaypointId(null); setPendingWaypointFrame(null);
918
761
  }
919
762
  function createLegacyCastHandlers(finitePatch, characterForRef) {
920
763
  function replaceCharacters(next) { return domain.run('cast.replace', { characters: next }); }
@@ -953,29 +796,14 @@ export function useCast(appContext) {
953
796
  domain.run('character.remove', { characterId: character.id });
954
797
  return { id: character.id };
955
798
  }
956
- function setLivePromptBlocks(args) {
957
- if (!Array.isArray(args.blocks)) throw new Error("Invalid blocks");
958
- const stamp = Date.now();
959
- const clips = args.blocks.map((block, i) => {
960
- const startFrame = Math.round(Number(block.startFrame));
961
- const endFrame = Math.round(Number(block.endFrame));
962
- if (!Number.isFinite(startFrame) || !Number.isFinite(endFrame) || endFrame <= startFrame) {
963
- throw new Error(`Invalid frame range on block ${i + 1}`);
964
- }
965
- if (typeof block.text !== "string" || !block.text.trim()) throw new Error(`Block ${i + 1} needs text`);
966
- return { id: `prompt-${stamp}-${i}`, startFrame, endFrame, text: block.text.trim() };
967
- });
968
- domain.run('character.setPromptBlocks', { characterId: domain.activeId, blocks: clips });
969
- return { blocks: clips.length };
970
- }
971
- return { add_character: addLiveCharacter, update_character: updateLiveCharacter, remove_character: removeLiveCharacter, set_prompt_blocks: setLivePromptBlocks };
799
+ return { add_character: addLiveCharacter, update_character: updateLiveCharacter, remove_character: removeLiveCharacter };
972
800
  }
973
801
  function toggleCharacterHidden(charId) { return domain.run('character.update', { characterId: charId, patch: { hidden: castMemberOf(charId).hidden !== true } }); }
974
802
  domain.snapshotMotion = snapshotNativeMotion;
975
803
  domain.syncLayer = () => {
976
804
  const entry = domain.read().find(entry => entry.id === appContext.shared.loadedLayerCharRef.current) ?? domain.read()[0];
977
805
  appContext.shared.bufferRef.current = { ...appContext.shared.bufferRef.current, ...entry.layer };
978
- setSelectedPromptId(id => entry.layer.promptClips.some(clip => clip.id === id) ? id : null);
806
+
979
807
  setActiveWaypointId(id => entry.layer.waypoints.some(waypoint => waypoint.id === id) ? id : null);
980
808
  };
981
809
  domain.loadView = () => { appContext.shared.loadedLayerCharRef.current = domain.activeId; setActiveCharacterId(domain.activeId); };
@@ -989,8 +817,7 @@ export function useCast(appContext) {
989
817
  const shots = appContext.storeDomain('shot');
990
818
  if (!shots) return;
991
819
  const current = domain.projection(), active = current.find(entry => entry.id === domain.activeId) ?? current[0];
992
- const extent = timelineContentExtent(current, active.id, appContext.shared.bufferRef.current.motion,
993
- active.layer.promptClips, appContext.shared.motionDomain.multiModelFootage?.frames);
820
+ const extent = timelineContentExtent(current, active.id, appContext.shared.bufferRef.current.motion, null);
994
821
  domain.setTimeline(Math.max(24, timelineSpan(extent, shots.read(), shots.state().frameCount)));
995
822
  };
996
823
  domain.extendTimeline = domain.syncTimeline;
@@ -1011,14 +838,12 @@ export function useCast(appContext) {
1011
838
  spawnCharacter, charKeyToHierarchyId, charIdFromHierarchyId, activeCharacterId, setActiveCharacterId,
1012
839
  rowIdForCharIndex, activeChar, selectActiveCharacterInHierarchy, activeCharIndex, activeRig, waitForRig,
1013
840
  ghostLayers, snapshotCast, changeInspectorCharacter, hasCharSheet,
1014
- setHasCharSheet, promptBlocksReveal, setPromptBlocksReveal, revealPromptBlocks, waypointMode,
841
+ setHasCharSheet, waypointMode,
1015
842
  setWaypointMode, waypoints, setWaypoints, activeWaypointId, setActiveWaypointId, pendingWaypointFrame,
1016
- setPendingWaypointFrame, promptClips, setPromptClips, editPromptClips, selectedPromptId,
1017
- setSelectedPromptId, photoPoseState, photoPoseError, setPhotoPoseError, allPoses, selectablePoses,
843
+ setPendingWaypointFrame, allPoses, selectablePoses,
1018
844
  posingIndex, posingChar, posedRig, setPosed, rootStart, queueRootWaypointFrame, castMemberOf,
1019
845
  addCharacterWaypoint, moveCharacterWaypoint, removeCharacterWaypoint, clearCharacterWaypoints,
1020
846
  addFloorWaypoint, moveWaypoint, removeWaypoint, toggleWaypointMode, openStudio, closeStudio,
1021
- saveCurrentPose, savePose, posePhotoFile, removePose, addPromptClip, changePromptClip,
1022
- PROMPT_BLOCK_MAX_FRAMES, resizePromptClip, movePromptClip, removePromptClip,
847
+ saveCurrentPose, savePose, removePose,
1023
848
  };
1024
849
  }
@@ -1,4 +1,4 @@
1
- import { rangePinTracks } from "../../ardy/range-pin.js";
1
+ import { rangePinTracks } from "../../motion/range-pin.js";
2
2
  import { ko } from "../../locale.js";
3
3
 
4
4
  export function ensureRangePinState(state) {
@@ -0,0 +1,51 @@
1
+ // What a saved take v3 is: the motion spec, the character placement and the scene as the
2
+ // compiler saw it (motionScene boxes), never the baked Float32 arrays. Compiling is
3
+ // deterministic, so compiling the source again rebuilds the same bones: this follows the
4
+ // motion.compile install path step for step (pipeline compileSpec, then bakeTake). Searched
5
+ // open parameters are already resolved in the stored spec, so no search runs again.
6
+ import { compileSpec } from "../../motion3/pipeline.js";
7
+ import { bakeTake } from "../../motion3/take.js";
8
+ import { motionScene } from "../../motion3/scene.js";
9
+ import { skeletonFor } from "../../motion3/rigs/index.js";
10
+ import { isTakeV3 } from "../../motion3/playback.js";
11
+ import { normalizeTakeEdit } from "../../motion3/take-edit.js";
12
+ export { renderTakeEdit } from "../../motion3/take-edit.js";
13
+
14
+ const TAKE_SCHEMA = "cozyclay.take.v3";
15
+ const SPEC_SCHEMA = "cozyclay.motion-spec.v1";
16
+ const TIMELINE_FPS = 24;
17
+ const plain = value => Boolean(value) && typeof value === "object" && !Array.isArray(value);
18
+ const finite3 = value => Array.isArray(value) && value.length === 3 && value.every(Number.isFinite);
19
+
20
+ /** The JSON source of an installed take v3 (null for any other motion). Skills, anchors and
21
+ * hinges may read any scene object, so the whole compile scene is kept. */
22
+ export function takeSource(take, sceneObjects = []) {
23
+ if (!isTakeV3(take) || !plain(take.spec)) return null;
24
+ return structuredClone({ schema: TAKE_SCHEMA, rig: take.rig, spec: take.spec,
25
+ placement: { position: take.placement?.position ?? [0, 0, 0], yaw: take.placement?.yaw ?? 0 }, scene: motionScene(sceneObjects) });
26
+ }
27
+
28
+ /** A saved source (with the Studio take id it carried), checked and owned by the caller; null when it is not one. */
29
+ export function normalizeTakeSource(value) {
30
+ if (!plain(value) || value.schema !== TAKE_SCHEMA || typeof value.rig !== "string") return null;
31
+ if (!plain(value.spec) || value.spec.schema !== SPEC_SCHEMA || !Number.isFinite(value.spec.frames)) return null;
32
+ if (!plain(value.placement) || !finite3(value.placement.position) || !Number.isFinite(value.placement.yaw)) return null;
33
+ const objects = plain(value.scene?.objects) ? value.scene.objects : {}, others = plain(value.scene?.others) ? { others: value.scene.others } : {};
34
+ return structuredClone({ schema: TAKE_SCHEMA, rig: value.rig, spec: value.spec,
35
+ placement: { position: value.placement.position, yaw: value.placement.yaw }, scene: { objects, ...others },
36
+ ...(typeof value.takeId === "string" && value.takeId ? { takeId: value.takeId } : {}),
37
+ ...(normalizeTakeEdit(value.edit, value.spec.frames) ? { edit: normalizeTakeEdit(value.edit, value.spec.frames) } : {}) });
38
+ }
39
+
40
+ /** What a scene saves for a motion layer's take descriptor: its source, take id and timing edit (take-edit.js), or null. */
41
+ export const savedTakeSource = descriptor => descriptor?.source ? { ...descriptor.source, takeId: descriptor.studioTakeId, ...(descriptor.edit ? { edit: descriptor.edit } : {}) } : null;
42
+
43
+ /** Compile a source back into the installed take (with `frames`, as motion.compile installs it).
44
+ * Leniently: a field a later, stricter validator does not know never blocks loading a saved take. */
45
+ export function compileTakeSource(source) {
46
+ const sk = skeletonFor(source?.rig);
47
+ if (!sk || !plain(source.spec)) return null;
48
+ const { out } = compileSpec({ fps: TIMELINE_FPS, ...source.spec }, { sk, scene: source.scene ?? { objects: {} } }, { lenient: true });
49
+ const take = bakeTake(sk, out, source.placement, { spec: source.spec, prompt: source.spec.label ?? "" });
50
+ return { ...take, frames: take.frameCount };
51
+ }