cozyclay 2.1.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (585) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +12 -30
  3. package/bin/agent/agent-routes.mjs +43 -116
  4. package/bin/agent/agent-runner.mjs +14 -15
  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/session-store.mjs +2 -2
  14. package/bin/agent/studio-context-budget.mjs +93 -0
  15. package/bin/agent/studio-motion-reference.mjs +23 -0
  16. package/bin/agent/studio-prompt.mjs +1 -1
  17. package/bin/agent/studio-rebase-text.mjs +32 -0
  18. package/bin/agent/studio-rebase.mjs +26 -39
  19. package/bin/agent/studio-tools.mjs +9 -28
  20. package/bin/agent/tool-arguments.mjs +49 -0
  21. package/bin/agent/turn-frames.mjs +66 -0
  22. package/bin/codex-auth.mjs +9 -2
  23. package/bin/cozyclay.mjs +10 -116
  24. package/bin/live/cli.mjs +3 -3
  25. package/bin/mcp-runtime.mjs +2 -12
  26. package/bin/package-signature.mjs +0 -4
  27. package/dist/app/index.html +7 -6
  28. package/dist/assets/EXRLoader-CvVIvGVE.js +1 -0
  29. package/dist/assets/analytics-BWCqdgWA.js +1 -0
  30. package/dist/assets/app-DfTCxaKk.js +5087 -0
  31. package/dist/assets/app-f-fkV5uP.css +1 -0
  32. package/dist/assets/compile-worker-BxKXh07s.js +5 -0
  33. package/dist/assets/fflate.module-KbGj5-H6.js +5 -0
  34. package/dist/assets/{first-shot-handoff-msLI71g1.js → first-shot-handoff-DNO8kv_N.js} +1 -1
  35. package/dist/assets/{landing-ChUvB_zL.js → landing-yfZaJkWc.js} +1 -1
  36. package/dist/assets/scene-asset-sync-U3kS2rvK.js +20 -0
  37. package/dist/assets/scene-asset-sync-_S8NQl5B.css +1 -0
  38. package/dist/assets/workflow-D78eiKTa.js +179 -0
  39. package/dist/cozyclay-package.json +1 -1
  40. package/dist/index.html +3 -3
  41. package/dist/sw.js +3 -6
  42. package/dist/workflow/index.html +5 -4
  43. package/mcp/LIVE-PROTOCOL.md +7 -47
  44. package/mcp/README.md +16 -26
  45. package/mcp/live-hub.mjs +6 -10
  46. package/mcp/package.json +1 -3
  47. package/mcp/tool-handlers.mjs +4 -168
  48. package/package.json +3 -22
  49. package/src/App.jsx +151 -2625
  50. package/src/agent-progress.js +80 -0
  51. package/src/agent-turn-mark.js +30 -0
  52. package/src/analytics.js +1 -19
  53. package/src/app-context.js +12 -2
  54. package/src/app-stage.jsx +2 -34
  55. package/src/asset-pane.jsx +6 -5
  56. package/src/camera-block.js +21 -0
  57. package/src/camera-direction.js +120 -0
  58. package/src/character-kind.js +3 -9
  59. package/src/command-bus.js +10 -8
  60. package/src/commands/cast.js +5 -34
  61. package/src/commands/elements/character.js +1 -1
  62. package/src/commands/elements/motion.js +1 -6
  63. package/src/commands/elements/object.js +6 -2
  64. package/src/commands/elements/shot.js +4 -1
  65. package/src/commands/elements.js +38 -14
  66. package/src/commands/index.js +3 -1
  67. package/src/commands/kits.js +37 -0
  68. package/src/commands/motion-timing.js +57 -0
  69. package/src/commands/motion.js +9 -152
  70. package/src/commands/motion3-compile.js +65 -0
  71. package/src/commands/motion3.js +214 -0
  72. package/src/commands/objects.js +6 -4
  73. package/src/commands/shot.js +55 -13
  74. package/src/commands/stage.js +14 -1
  75. package/src/commands/view.js +4 -1
  76. package/src/document-mirrors.js +42 -0
  77. package/src/document-store.js +4 -0
  78. package/src/domains/cast.js +19 -194
  79. package/src/domains/motion/motion-range-pin-rules.js +1 -1
  80. package/src/domains/motion/take-source.js +53 -0
  81. package/src/domains/motion.js +60 -1838
  82. package/src/domains/scenes.js +12 -55
  83. package/src/domains/shots.js +2 -2
  84. package/src/domains/stage.js +4 -2
  85. package/src/draft-ghost.js +47 -0
  86. package/src/draft-ghost.jsx +129 -0
  87. package/src/dualview.jsx +4 -3
  88. package/src/effects/EffectsLayer.jsx +112 -0
  89. package/src/effects/effect-meshes.js +232 -0
  90. package/src/effects/effect-record.js +103 -0
  91. package/src/effects/emitter.js +59 -0
  92. package/src/effects/simulate.js +261 -0
  93. package/src/effects/state.js +59 -0
  94. package/src/execution-telemetry.js +2 -3
  95. package/src/first-success-guide.jsx +5 -5
  96. package/src/ghost-set.js +257 -0
  97. package/src/held-object-edit.jsx +113 -0
  98. package/src/held-object-pose.js +175 -0
  99. package/src/hierarchy-model.js +1 -1
  100. package/src/hierarchy-panel.jsx +1 -1
  101. package/src/imported-mesh.jsx +103 -0
  102. package/src/kits/held.js +84 -0
  103. package/src/kits/index.js +70 -0
  104. package/src/kits/smoking.js +57 -0
  105. package/src/light-blockers.js +93 -0
  106. package/src/motion/beat-board-model.js +84 -0
  107. package/src/motion/beat-board.css +124 -0
  108. package/src/motion/beat-board.jsx +60 -0
  109. package/src/motion/center-of-mass.js +66 -0
  110. package/src/motion/fix-collisions.js +850 -0
  111. package/src/motion/physics-review.js +118 -0
  112. package/src/{ardy → motion}/physics-support.js +1 -76
  113. package/src/motion/rig-snapshot.js +22 -0
  114. package/src/motion/take-segments.jsx +140 -0
  115. package/src/{ardy → motion}/timeline-coordinates.js +0 -21
  116. package/src/{ardy → motion}/timeline.css +1 -2
  117. package/src/{ardy → motion}/timeline.jsx +42 -413
  118. package/src/motion/waypoints.js +76 -0
  119. package/src/motion3/beats.js +83 -0
  120. package/src/motion3/body.js +158 -0
  121. package/src/motion3/bones.js +47 -0
  122. package/src/motion3/carried.js +47 -0
  123. package/src/motion3/compile-job.js +79 -0
  124. package/src/motion3/compile-worker.js +10 -0
  125. package/src/motion3/compiler/anchors.js +113 -0
  126. package/src/motion3/compiler/arm-orient.js +128 -0
  127. package/src/motion3/compiler/channels.js +125 -0
  128. package/src/motion3/compiler/compile.js +205 -0
  129. package/src/motion3/compiler/gait-rhythm.js +97 -0
  130. package/src/motion3/compiler/grip.js +171 -0
  131. package/src/motion3/compiler/head-steady.js +48 -0
  132. package/src/motion3/compiler/hold.js +134 -0
  133. package/src/motion3/compiler/idle.js +113 -0
  134. package/src/motion3/compiler/limbs.js +197 -0
  135. package/src/motion3/compiler/math.js +72 -0
  136. package/src/motion3/compiler/pose.js +177 -0
  137. package/src/motion3/compiler/quat.js +49 -0
  138. package/src/motion3/compiler/skeleton.js +74 -0
  139. package/src/motion3/compiler/validate-common.js +32 -0
  140. package/src/motion3/compiler/validate-goals.js +118 -0
  141. package/src/motion3/compiler/validate-objects.js +144 -0
  142. package/src/motion3/compiler/validate-parts.js +118 -0
  143. package/src/motion3/compiler/validate.js +122 -0
  144. package/src/motion3/compiler/vocab.js +74 -0
  145. package/src/motion3/compiler/walk-pelvis.js +275 -0
  146. package/src/motion3/compiler/walk.js +207 -0
  147. package/src/motion3/compiler/wrist-clamp.js +32 -0
  148. package/src/motion3/delta.js +47 -0
  149. package/src/motion3/describe.js +177 -0
  150. package/src/motion3/docs.js +27 -0
  151. package/src/motion3/edit-carry.js +21 -0
  152. package/src/motion3/fix/ease.js +16 -0
  153. package/src/motion3/fix/ground.js +37 -0
  154. package/src/motion3/fix/index.js +52 -0
  155. package/src/motion3/fix/push.js +71 -0
  156. package/src/motion3/fix/reach.js +46 -0
  157. package/src/motion3/fix/retime.js +79 -0
  158. package/src/motion3/fix/self.js +211 -0
  159. package/src/motion3/fix/slide.js +70 -0
  160. package/src/motion3/fix/turn.js +51 -0
  161. package/src/motion3/follow.js +39 -0
  162. package/src/motion3/free-motion.js +204 -0
  163. package/src/motion3/grip-choice.js +130 -0
  164. package/src/motion3/hold-plan.js +157 -0
  165. package/src/motion3/json-patch.js +77 -0
  166. package/src/motion3/key-aim.js +105 -0
  167. package/src/motion3/key-edit.js +82 -0
  168. package/src/motion3/lenient.js +127 -0
  169. package/src/motion3/object-keys.js +236 -0
  170. package/src/motion3/object-pose.js +182 -0
  171. package/src/motion3/object-tracks.js +12 -0
  172. package/src/motion3/people.js +82 -0
  173. package/src/motion3/pipeline.js +102 -0
  174. package/src/motion3/playback.js +51 -0
  175. package/src/motion3/probes.js +91 -0
  176. package/src/motion3/qa/body-checks.js +34 -0
  177. package/src/motion3/qa/check-names.js +14 -0
  178. package/src/motion3/qa/checks.js +125 -0
  179. package/src/motion3/qa/contact-checks.js +51 -0
  180. package/src/motion3/qa/explain.js +80 -0
  181. package/src/motion3/qa/fmt.js +5 -0
  182. package/src/motion3/qa/foot-checks.js +72 -0
  183. package/src/motion3/qa/geometry.js +77 -0
  184. package/src/motion3/qa/goals.js +191 -0
  185. package/src/motion3/qa/ground.js +60 -0
  186. package/src/motion3/qa/hints-contact.js +195 -0
  187. package/src/motion3/qa/hints-goal.js +160 -0
  188. package/src/motion3/qa/hints-knee.js +24 -0
  189. package/src/motion3/qa/hints-motion.js +209 -0
  190. package/src/motion3/qa/hints-object.js +91 -0
  191. package/src/motion3/qa/index.js +44 -0
  192. package/src/motion3/qa/key-checks.js +82 -0
  193. package/src/motion3/qa/near.js +96 -0
  194. package/src/motion3/qa/object-checks.js +135 -0
  195. package/src/motion3/qa/patch.js +161 -0
  196. package/src/motion3/qa/people-checks.js +37 -0
  197. package/src/motion3/qa/severity.js +38 -0
  198. package/src/motion3/qa/spec-checks.js +65 -0
  199. package/src/motion3/qa/style.js +228 -0
  200. package/src/motion3/qa/wrist-checks.js +69 -0
  201. package/src/motion3/qa/wrist-obs.js +60 -0
  202. package/src/motion3/refs.js +129 -0
  203. package/src/motion3/repair-tune.js +121 -0
  204. package/src/motion3/repair.js +83 -0
  205. package/src/motion3/report.js +67 -0
  206. package/src/motion3/rigs/index.js +14 -0
  207. package/src/motion3/rigs/x-bot-tpose-body.json +1 -0
  208. package/src/motion3/rigs/x-bot-tpose.json +1 -0
  209. package/src/motion3/rigs/y-bot-tpose-body.json +1 -0
  210. package/src/motion3/rigs/y-bot-tpose.json +1 -0
  211. package/src/motion3/scene.js +60 -0
  212. package/src/motion3/schema/brief.js +89 -0
  213. package/src/motion3/schema/fields.js +44 -0
  214. package/src/motion3/schema/spec-examples.js +46 -0
  215. package/src/motion3/schema/topics.js +113 -0
  216. package/src/motion3/schema/types.js +149 -0
  217. package/src/motion3/search.js +117 -0
  218. package/src/motion3/second-hand.js +112 -0
  219. package/src/motion3/settle.js +136 -0
  220. package/src/motion3/skills/basic.js +83 -0
  221. package/src/motion3/skills/book.js +76 -0
  222. package/src/motion3/skills/car.js +145 -0
  223. package/src/motion3/skills/flip.js +200 -0
  224. package/src/motion3/skills/frames-auto.js +29 -0
  225. package/src/motion3/skills/impact.js +109 -0
  226. package/src/motion3/skills/index.js +85 -0
  227. package/src/motion3/skills/info.js +80 -0
  228. package/src/motion3/skills/smoke-kit.js +109 -0
  229. package/src/motion3/skills/smoke.js +160 -0
  230. package/src/motion3/spec-store.js +59 -0
  231. package/src/motion3/take-edit.js +155 -0
  232. package/src/motion3/take.js +63 -0
  233. package/src/motion3/timeline.js +127 -0
  234. package/src/motion3/views.js +121 -0
  235. package/src/motion3/walk-plan.js +119 -0
  236. package/src/object-catalog.jsx +7 -1
  237. package/src/object-colors.js +98 -0
  238. package/src/object-gizmo-parts.js +115 -0
  239. package/src/object-gizmo.jsx +37 -122
  240. package/src/object-glow.js +139 -0
  241. package/src/object-hidden.js +33 -0
  242. package/src/object-look.js +196 -0
  243. package/src/object-size.js +10 -0
  244. package/src/object-travel.js +71 -6
  245. package/src/panels/CameraPanel.jsx +7 -7
  246. package/src/panels/HdrEnvironmentControls.jsx +59 -0
  247. package/src/panels/LightPanel.jsx +25 -4
  248. package/src/panels/ObjectLookPanel.jsx +88 -0
  249. package/src/panels/PosePanel.jsx +2 -17
  250. package/src/panels/RigControlPanel.jsx +5 -53
  251. package/src/panels/SubjectBox.jsx +4 -1
  252. package/src/panels/details.css +14 -0
  253. package/src/posestudio.jsx +4 -27
  254. package/src/project-browser.jsx +3 -4
  255. package/src/project-resources.js +18 -31
  256. package/src/project.js +13 -104
  257. package/src/props.jsx +25 -280
  258. package/src/qa-label.js +25 -0
  259. package/src/rail-dot-drag.js +23 -0
  260. package/src/render-passes.js +10 -0
  261. package/src/resource-status.jsx +1 -0
  262. package/src/result-modal.jsx +4 -19
  263. package/src/room.jsx +20 -12
  264. package/src/scene-assets.js +8 -6
  265. package/src/scene-light-place.js +72 -0
  266. package/src/scene-lights.jsx +148 -0
  267. package/src/scene-objects.js +31 -139
  268. package/src/scenes.js +15 -105
  269. package/src/semantic-edit.js +2 -5
  270. package/src/set-pieces.jsx +183 -0
  271. package/src/settings-menu.jsx +3 -11
  272. package/src/shell/BottomDock.jsx +9 -51
  273. package/src/shell/DetailsSlot.jsx +16 -200
  274. package/src/shell/GhostsMenuGroup.jsx +74 -0
  275. package/src/shell/LibrarySlot.jsx +1 -3
  276. package/src/shell/MenuBar.jsx +3 -3
  277. package/src/shell/PreferencesDialog.jsx +15 -264
  278. package/src/shell/PreferencesSlot.jsx +2 -8
  279. package/src/shell/TopBar.jsx +5 -84
  280. package/src/shell/ViewportToolbar.jsx +10 -70
  281. package/src/shell/agent-glass.css +19 -6
  282. package/src/shell/details-selection.js +42 -0
  283. package/src/shell/ghosts-menu.css +22 -0
  284. package/src/shell/glass-regions.css +29 -3
  285. package/src/shell/preferences.css +6 -1
  286. package/src/shot-authoring.js +4 -7
  287. package/src/soft-shadows.js +37 -0
  288. package/src/stage-attach-frames.js +12 -12
  289. package/src/stage-canvas-rigs.jsx +3 -3
  290. package/src/stage-capture.jsx +42 -8
  291. package/src/stage-characters.jsx +22 -216
  292. package/src/stage-editor-gizmos.jsx +6 -6
  293. package/src/stage-environment.js +93 -0
  294. package/src/stage-hdr-builtins.js +107 -0
  295. package/src/stage-hdr-image.js +116 -0
  296. package/src/stage-hdr-library.js +70 -0
  297. package/src/stage-hdr-map.js +94 -0
  298. package/src/stage-hdr.js +130 -0
  299. package/src/stage-lighting.js +149 -0
  300. package/src/stage-occlusion.js +210 -0
  301. package/src/stage-sky.jsx +159 -0
  302. package/src/stage-startup-defaults.js +5 -9
  303. package/src/studio-actions.js +16 -14
  304. package/src/studio-agent-commands.js +19 -16
  305. package/src/studio-agent-motion.js +9 -9
  306. package/src/studio-agent-protocol.js +47 -77
  307. package/src/studio-app-binding.js +27 -47
  308. package/src/studio-asset-list.js +17 -0
  309. package/src/studio-contact-sheet.js +37 -5
  310. package/src/studio-elements.js +27 -7
  311. package/src/studio-entity-bounds.js +18 -0
  312. package/src/studio-error-codes.js +15 -0
  313. package/src/studio-export-framing.js +152 -0
  314. package/src/studio-lighting-check.js +103 -0
  315. package/src/studio-motion-visual.js +150 -0
  316. package/src/studio-schema-errors.js +80 -0
  317. package/src/studio-support-gap.js +74 -0
  318. package/src/styles.css +1 -19
  319. package/src/timeline-defaults.js +5 -0
  320. package/src/timeline-extent.js +8 -20
  321. package/src/tutorial-walk.js +17 -0
  322. package/src/ui-scrub.js +1 -1
  323. package/src/use-shot-camera-tracks.js +12 -0
  324. package/src/view-ghosts.js +97 -0
  325. package/src/view-ghosts.jsx +49 -0
  326. package/src/workflow/AgentPanel.jsx +47 -166
  327. package/src/workflow/AgentProgressCard.jsx +109 -0
  328. package/src/workflow/AgentReplyText.jsx +37 -0
  329. package/src/workflow/AgentTurnSteps.jsx +84 -0
  330. package/src/workflow/LoginPanel.jsx +140 -0
  331. package/src/workflow/WorkflowBuilder.jsx +7 -23
  332. package/src/workflow/agent-client.js +54 -51
  333. package/src/workflow/agent-panel.css +71 -1
  334. package/src/workflow/agent-progress-card.css +167 -0
  335. package/src/workflow/agent-progress-view.js +47 -0
  336. package/src/workflow/agent-turn-steps.css +113 -0
  337. package/src/workflow/agent-turn.js +191 -0
  338. package/src/workflow/login-client.js +34 -0
  339. package/src/workflow/motion-input.js +18 -31
  340. package/src/workflow/node-schema.js +1 -1
  341. package/src/workflow/reply-markdown.js +69 -0
  342. package/src/workflow/scene-asset-sync.js +8 -8
  343. package/tools/agent-session-stats.mjs +61 -0
  344. package/tools/dev-full.mjs +5 -56
  345. package/tools/eslint-baseline.json +12 -13
  346. package/tools/knip-baseline.json +0 -179
  347. package/tools/loc-baseline.json +31 -81
  348. package/tools/motion3/extract-body.mjs +103 -0
  349. package/tools/motion3/extract-rig.mjs +85 -0
  350. package/tools/process-supervisor.mjs +0 -88
  351. package/tools/run-tests.mjs +9 -125
  352. package/bin/agent/motion-runtime.mjs +0 -76
  353. package/dist/ardy/cskel27-rest.json +0 -557
  354. package/dist/assets/analytics-C9pMpW7s.js +0 -1
  355. package/dist/assets/app-B_2XB9rw.css +0 -1
  356. package/dist/assets/app-DAuvKPP8.js +0 -4920
  357. package/dist/assets/config-Bx7pYsD9.js +0 -1
  358. package/dist/assets/config-DeoFTYzb.css +0 -1
  359. package/dist/assets/demo-CvKuBgy5.js +0 -1
  360. package/dist/assets/scene-asset-sync-DKkpjKBV.js +0 -19
  361. package/dist/assets/scene-asset-sync-DjJ_cJ2R.css +0 -1
  362. package/dist/assets/ticket-BPk2Ni95.js +0 -1
  363. package/dist/assets/workflow-jJRBR94Z.js +0 -179
  364. package/dist/demo/walk-then-stop.npz +0 -0
  365. package/mcp/ardy-prompts.mjs +0 -218
  366. package/src/ardy/auto-fix-panel.css +0 -108
  367. package/src/ardy/auto-physics.js +0 -1194
  368. package/src/ardy/client.js +0 -153
  369. package/src/ardy/convert.js +0 -313
  370. package/src/ardy/cskel27-neutral.js +0 -39
  371. package/src/ardy/cskel27.js +0 -77
  372. package/src/ardy/export.js +0 -165
  373. package/src/ardy/fix-collisions.js +0 -2257
  374. package/src/ardy/foot-lock.js +0 -230
  375. package/src/ardy/motion-calibration.js +0 -118
  376. package/src/ardy/motion-edit.js +0 -213
  377. package/src/ardy/motion-url.js +0 -55
  378. package/src/ardy/mp4-duration.js +0 -102
  379. package/src/ardy/npz.js +0 -595
  380. package/src/ardy/physics-panel.css +0 -21
  381. package/src/ardy/physics-panel.jsx +0 -89
  382. package/src/ardy/physics-refine.js +0 -111
  383. package/src/ardy/physics-review.js +0 -567
  384. package/src/ardy/physics-temporal.js +0 -54
  385. package/src/ardy/platform-fit-panel.css +0 -64
  386. package/src/ardy/platform-fit-panel.jsx +0 -41
  387. package/src/ardy/platform-fit.js +0 -326
  388. package/src/ardy/playback.js +0 -711
  389. package/src/ardy/pose-pin.js +0 -97
  390. package/src/ardy/prompt-clips.js +0 -30
  391. package/src/ardy/retime.js +0 -211
  392. package/src/ardy/root-drop.js +0 -369
  393. package/src/ardy/timeline-resize.js +0 -13
  394. package/src/ardy/to-cskel27.js +0 -225
  395. package/src/ardy/trim.js +0 -33
  396. package/src/ardy/waypoints.js +0 -369
  397. package/src/ardy-bridge-contract.js +0 -281
  398. package/src/domains/motion/motion-video-capture.js +0 -664
  399. package/src/i2v-motion-client.js +0 -77
  400. package/src/i2v-motion-studio.jsx +0 -180
  401. package/src/line-edit.js +0 -1348
  402. package/src/motion/generation.js +0 -105
  403. package/src/motion-readiness-ui.jsx +0 -67
  404. package/src/motion-readiness.js +0 -40
  405. package/src/motion-resources.js +0 -177
  406. package/src/motion-store.js +0 -65
  407. package/src/motion-trail.js +0 -601
  408. package/src/multimodel-ingest.js +0 -394
  409. package/src/panels/PromptBlocksPanel.jsx +0 -444
  410. package/src/panels/VideoCapturePanel.jsx +0 -181
  411. package/src/pose-extract/browser.js +0 -42
  412. package/src/pose-extract/detector.js +0 -100
  413. package/src/pose-extract/fit.js +0 -227
  414. package/src/pose-extract/image-frame.js +0 -51
  415. package/src/pose-extract/index.js +0 -58
  416. package/src/pose-extract/keyframes.js +0 -74
  417. package/src/pose-extract/landmarks.js +0 -162
  418. package/src/pose-extract/mirror.js +0 -153
  419. package/src/pose-extract/take.js +0 -131
  420. package/src/pose-extract/video-frames.js +0 -91
  421. package/src/take-recipe.js +0 -165
  422. package/src/trail-key-conflicts.js +0 -39
  423. package/src/trail-pick.js +0 -59
  424. package/src/use-i2v-capture-modal.js +0 -15
  425. package/tools/ardy/BRIDGE.md +0 -37
  426. package/tools/ardy/GVHMR-NPZ.md +0 -68
  427. package/tools/ardy/README.md +0 -124
  428. package/tools/ardy/__pycache__/cclay_gvhmr_worker.cpython-313.pyc +0 -0
  429. package/tools/ardy/artifacts.mjs +0 -34
  430. package/tools/ardy/bridge.mjs +0 -1732
  431. package/tools/ardy/bvh-cskel27.mjs +0 -1265
  432. package/tools/ardy/cclay_constrained_generate.py +0 -561
  433. package/tools/ardy/cclay_gvhmr_worker.py +0 -264
  434. package/tools/ardy/cclay_motion_edit.py +0 -510
  435. package/tools/ardy/cclay_sequence_generate.py +0 -705
  436. package/tools/ardy/cclay_worker.py +0 -304
  437. package/tools/ardy/dump-npz.py +0 -205
  438. package/tools/ardy/extract-rest.mjs +0 -299
  439. package/tools/ardy/extract.mjs +0 -507
  440. package/tools/ardy/footage.mjs +0 -467
  441. package/tools/ardy/gvhmr-floor.mjs +0 -102
  442. package/tools/ardy/gvhmr-to-cskel27.mjs +0 -21
  443. package/tools/ardy/gvhmr_fastpath.py +0 -168
  444. package/tools/ardy/gvhmr_trajectory.py +0 -240
  445. package/tools/ardy/merge-text-encoder.py +0 -160
  446. package/tools/ardy/mocap-metrics.mjs +0 -200
  447. package/tools/ardy/mocap-quality-gate.mjs +0 -110
  448. package/tools/ardy/motion-stabilize.mjs +0 -348
  449. package/tools/ardy/npz.mjs +0 -414
  450. package/tools/ardy/pose-to-npz.mjs +0 -106
  451. package/tools/ardy/prompt-limits.mjs +0 -5
  452. package/tools/ardy/run-edit-on-box.sh +0 -73
  453. package/tools/ardy/run-local.mjs +0 -233
  454. package/tools/ardy/run-on-box.sh +0 -593
  455. package/tools/ardy/run-sequence-on-box.sh +0 -177
  456. package/tools/ardy/runners/gvhmr-worker.mjs +0 -206
  457. package/tools/ardy/runners/index.mjs +0 -18
  458. package/tools/ardy/runners/local.mjs +0 -455
  459. package/tools/ardy/runners/proc.mjs +0 -125
  460. package/tools/ardy/runners/remote.mjs +0 -252
  461. package/tools/ardy/setup-local.mjs +0 -189
  462. package/tools/ardy/setup-text-encoder-on-box.sh +0 -93
  463. package/tools/ardy/setup-text-encoder.py +0 -306
  464. package/tools/ardy/smpl-cskel27.mjs +0 -178
  465. package/tools/ardy/visual-qa.mjs +0 -196
  466. package/tools/ardy/vq-car.mjs +0 -52
  467. package/tools/bench/EXP3.md +0 -61
  468. package/tools/bench/cclay_bench_extract_incam.py +0 -125
  469. package/tools/bench/cclay_bench_extract_obs.py +0 -204
  470. package/tools/bench/cclay_bench_runner.py +0 -42
  471. package/tools/bench/cube-contact.mjs +0 -162
  472. package/tools/bench/exp3.mjs +0 -152
  473. package/tools/bench/extract-bench-lib.mjs +0 -216
  474. package/tools/bench/extract-bench.mjs +0 -302
  475. package/tools/bench/fal-generate.mjs +0 -88
  476. package/tools/bench/fit/README.md +0 -189
  477. package/tools/bench/fit/camera.mjs +0 -59
  478. package/tools/bench/fit/contact.mjs +0 -419
  479. package/tools/bench/fit/footlock.mjs +0 -234
  480. package/tools/bench/fit/motion.mjs +0 -85
  481. package/tools/bench/fit/pin.mjs +0 -27
  482. package/tools/bench/fit/remote.mjs +0 -105
  483. package/tools/bench/fit-bench.mjs +0 -126
  484. package/tools/bench/fit-sanity.mjs +0 -45
  485. package/tools/bench/metrics.mjs +0 -313
  486. package/tools/bench/obs/depth.mjs +0 -258
  487. package/tools/bench/obs/extrinsics.mjs +0 -175
  488. package/tools/bench/obs/fit_mannequin_betas.py +0 -340
  489. package/tools/bench/obs/ground.mjs +0 -294
  490. package/tools/bench/obs/heading.mjs +0 -151
  491. package/tools/bench/obs/ladder.mjs +0 -555
  492. package/tools/bench/obs/mannequin-betas.json +0 -124
  493. package/tools/bench/obs/remote.mjs +0 -83
  494. package/tools/bench/obs/rest_joints.py +0 -52
  495. package/tools/bench/obs/ybot-targets.mjs +0 -49
  496. package/tools/bench/obs-bench.mjs +0 -520
  497. package/tools/bench/score.mjs +0 -343
  498. package/tools/bench/summarize.mjs +0 -86
  499. package/tools/demo-worker/README.md +0 -137
  500. package/tools/demo-worker/api-client.mjs +0 -233
  501. package/tools/demo-worker/generate.mjs +0 -301
  502. package/tools/demo-worker/index.mjs +0 -466
  503. package/tools/demo-worker/sign-core.mjs +0 -112
  504. package/tools/demo-worker/sign.mjs +0 -161
  505. package/tools/gt-render/browser.mjs +0 -182
  506. package/tools/gt-render/camera-math.mjs +0 -276
  507. package/tools/gt-render/page.mjs +0 -267
  508. package/tools/gt-render/render.mjs +0 -514
  509. package/tools/gt-render/scene-box.mjs +0 -31
  510. package/tools/gt-render/take-transform.mjs +0 -87
  511. package/tools/kimodo/compare-seam.mjs +0 -108
  512. package/tools/kimodo/constraints.mjs +0 -244
  513. package/tools/kimodo/edit.mjs +0 -259
  514. package/tools/kimodo/effector-constraints.mjs +0 -200
  515. package/tools/kimodo/generate.mjs +0 -646
  516. package/tools/kimodo/local-output.mjs +0 -265
  517. package/tools/kimodo/measure-pose.mjs +0 -65
  518. package/tools/kimodo/measure-preserve.mjs +0 -899
  519. package/tools/kimodo/measure-waypoints.mjs +0 -55
  520. package/tools/kimodo/mlx-generate.py +0 -111
  521. package/tools/kimodo/pose-constraints.mjs +0 -248
  522. package/tools/kimodo/preserve-mask.mjs +0 -543
  523. package/tools/kimodo/read-npz.mjs +0 -189
  524. package/tools/kimodo/run-edit-on-box.mjs +0 -155
  525. package/tools/kimodo/run-sequence-on-box.mjs +0 -178
  526. package/tools/kimodo/runner.mjs +0 -284
  527. package/tools/kimodo/seam-batch.mjs +0 -77
  528. package/tools/kimodo/setup-local.mjs +0 -30
  529. package/tools/kimodo/setup-on-box.sh +0 -339
  530. package/tools/kimodo/soma77-to-cskel27.mjs +0 -305
  531. package/tools/morphgs/assets/gen_truth.py +0 -39
  532. package/tools/morphgs/assets/mesh_ori_rig.txt +0 -27
  533. package/tools/morphgs/assets/playback-check.mjs +0 -30
  534. package/tools/morphgs/demo-gate.sh +0 -26
  535. package/tools/morphgs/fbx2morphgs.mjs +0 -68
  536. package/tools/morphgs/morphgs-to-cskel27.mjs +0 -105
  537. package/tools/morphgs/patches/preprocess_src-none-mode.patch +0 -76
  538. package/tools/morphgs/setup-on-cluster.sh +0 -126
  539. package/tools/projflow/driver.py +0 -1069
  540. package/tools/projflow/generate.mjs +0 -805
  541. package/tools/projflow/hml22-to-cskel27.mjs +0 -735
  542. package/tools/projflow/line-edit-job.mjs +0 -547
  543. package/tools/projflow/replay.mjs +0 -452
  544. package/tools/projflow/runner.mjs +0 -269
  545. package/tools/projflow/service.mjs +0 -742
  546. package/tools/track/DESIGN.md +0 -513
  547. package/tools/track/backfill-provenance.mjs +0 -116
  548. package/tools/track/budget.mjs +0 -8
  549. package/tools/track/check-rig.mjs +0 -209
  550. package/tools/track/diagnostics.schema.json +0 -60
  551. package/tools/track/export-rig.mjs +0 -256
  552. package/tools/track/fallback.mjs +0 -7
  553. package/tools/track/fk-parity-fixture.mjs +0 -161
  554. package/tools/track/gate.mjs +0 -349
  555. package/tools/track/masks.mjs +0 -318
  556. package/tools/track/metrics.mjs +0 -201
  557. package/tools/track/publish-obs.mjs +0 -108
  558. package/tools/track/py/check_env.py +0 -61
  559. package/tools/track/py/eval_lr.py +0 -229
  560. package/tools/track/py/lr_viterbi.py +0 -294
  561. package/tools/track/py/masks.py +0 -405
  562. package/tools/track/py/objective.py +0 -382
  563. package/tools/track/py/rig.py +0 -508
  564. package/tools/track/py/scene.py +0 -326
  565. package/tools/track/py/test_joint_indices.py +0 -123
  566. package/tools/track/py/test_lr_viterbi.py +0 -195
  567. package/tools/track/py/test_masks.py +0 -229
  568. package/tools/track/py/test_rig.py +0 -288
  569. package/tools/track/py/test_scene.py +0 -354
  570. package/tools/track/py/test_track.py +0 -328
  571. package/tools/track/py/track.py +0 -411
  572. package/tools/track/remote.mjs +0 -140
  573. package/tools/track/rig-dump.mjs +0 -227
  574. package/tools/track/run-box-tests.mjs +0 -14
  575. package/tools/track/run-box.mjs +0 -168
  576. package/tools/track/setup-box.sh +0 -59
  577. package/tools/track/study-2d.mjs +0 -728
  578. /package/src/{ardy → motion}/collision-blockers.js +0 -0
  579. /package/src/{ardy → motion}/ground.js +0 -0
  580. /package/src/{ardy → motion}/ik-drag.js +0 -0
  581. /package/src/{ardy → motion}/ik-key-json.js +0 -0
  582. /package/src/{ardy → motion}/ik.js +0 -0
  583. /package/src/{ardy → motion}/physics-surface.js +0 -0
  584. /package/src/{ardy → motion}/playback-clock.js +0 -0
  585. /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,53 @@
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), ...(plain(take.people) ? { people: take.people } : {}) } });
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
+ // the joints a person anchor named when it was compiled (people.js keptPeople)
35
+ const people = plain(value.scene?.people) && Object.values(value.scene.people).every(p => plain(p) && Array.isArray(p.names) && Array.isArray(p.P) && p.P.length === p.frames * p.names.length * 3) ? { people: value.scene.people } : {};
36
+ return structuredClone({ schema: TAKE_SCHEMA, rig: value.rig, spec: value.spec,
37
+ placement: { position: value.placement.position, yaw: value.placement.yaw }, scene: { objects, ...others, ...people },
38
+ ...(typeof value.takeId === "string" && value.takeId ? { takeId: value.takeId } : {}),
39
+ ...(normalizeTakeEdit(value.edit, value.spec.frames) ? { edit: normalizeTakeEdit(value.edit, value.spec.frames) } : {}) });
40
+ }
41
+
42
+ /** What a scene saves for a motion layer's take descriptor: its source, take id and timing edit (take-edit.js), or null. */
43
+ export const savedTakeSource = descriptor => descriptor?.source ? { ...descriptor.source, takeId: descriptor.studioTakeId, ...(descriptor.edit ? { edit: descriptor.edit } : {}) } : null;
44
+
45
+ /** Compile a source back into the installed take (with `frames`, as motion.compile installs it).
46
+ * Leniently: a field a later, stricter validator does not know never blocks loading a saved take. */
47
+ export function compileTakeSource(source) {
48
+ const sk = skeletonFor(source?.rig);
49
+ if (!sk || !plain(source.spec)) return null;
50
+ const { out } = compileSpec({ fps: TIMELINE_FPS, ...source.spec }, { sk, scene: source.scene ?? { objects: {} } }, { lenient: true });
51
+ const take = bakeTake(sk, out, source.placement, { spec: source.spec, prompt: source.spec.label ?? "" });
52
+ return { ...take, frames: take.frameCount };
53
+ }