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
@@ -2,7 +2,6 @@ import { useEffect, useMemo, useRef, useState } from "react";
2
2
  import { createPortal } from "react-dom";
3
3
  import { getAnalyticsOptOut, setAnalyticsOptOut } from "../analytics.js";
4
4
  import { loadAutoColor, saveAutoColor } from "../auto-color.js";
5
- import { motionReadinessMessage } from "../motion-readiness-ui.jsx";
6
5
  import { ko, LOCALE, setLocale } from "../locale.js";
7
6
  import { readStoredGridView, writeStoredGridView } from "../grid-view.js";
8
7
  import { readTheme, saveTheme } from "../theme.js";
@@ -13,75 +12,31 @@ const LANGUAGES = [
13
12
  { id: "ko", label: "한국어", action: "한국어로 전환" },
14
13
  ];
15
14
 
15
+ // Only pages whose settings reach the editor are listed; a control that
16
+ // changes nothing is not offered.
16
17
  const NAV_GROUPS = [
17
18
  {
18
19
  label: ko("General", "일반"),
19
20
  items: [
20
21
  { id: "Appearance", label: ko("Appearance", "모양") },
21
22
  { id: "Viewport", label: ko("Viewport", "뷰포트") },
22
- { id: "Input & Camera", label: ko("Input & Camera", "입력 및 카메라") },
23
23
  { id: "Hotkeys", label: ko("Hotkeys", "단축키") },
24
24
  ],
25
25
  },
26
- {
27
- label: ko("Motion", "모션"),
28
- items: [
29
- { id: "ARDY Connection", label: ko("ARDY Connection", "ARDY 연결") },
30
- { id: "IK Correction", label: ko("IK Correction", "IK 보정") },
31
- ],
32
- },
33
- {
34
- label: ko("Integrations", "통합"),
35
- items: [{ id: "MCP Server", label: ko("MCP Server", "MCP 서버") }],
36
- },
37
- {
38
- label: ko("Project", "프로젝트"),
39
- items: [
40
- { id: "Units & Frame rate", label: ko("Units & Frame rate", "단위 및 프레임 레이트") },
41
- { id: "Autosave", label: ko("Autosave", "자동 저장") },
42
- ],
43
- },
44
26
  ];
27
+ const NAV_LABELS = Object.fromEntries(NAV_GROUPS.flatMap((group) => group.items.map((item) => [item.id, item.label])));
28
+
29
+ const MOD = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform ?? "") ? "⌘" : "Ctrl ";
45
30
 
46
31
  const HOTKEYS = [
47
32
  ["Move", "W", "이동"],
48
33
  ["Rotate", "E", "회전"],
49
34
  ["Scale", "R", "크기 조절"],
50
35
  ["Frame selection", "F", "선택 프레임"],
51
- ["Duplicate", "Ctrl D", "복제"],
36
+ ["Duplicate", `${MOD}D`, "복제"],
52
37
  ["Drop to floor", "End", "바닥에 놓기"],
53
38
  ];
54
39
 
55
- const PREFERENCE_KEYS = Object.freeze({
56
- grid: "cozyclay.grid-view.v1",
57
- invertY: "cozyclay.preferences.invert-y.v1",
58
- orbit: "cozyclay.preferences.orbit-selection.v1",
59
- snap: "cozyclay.preferences.snapping.v1",
60
- ctrlSnap: "cozyclay.preferences.ctrl-snapping.v1",
61
- footLock: "cozyclay.preferences.foot-lock.v1",
62
- bodyContact: "cozyclay.preferences.body-contact.v1",
63
- autosave: "cozyclay.preferences.autosave.v1",
64
- });
65
-
66
- function readFlag(key, fallback = false) {
67
- try {
68
- return localStorage.getItem(key) === "1";
69
- } catch {
70
- return fallback;
71
- }
72
- }
73
-
74
- function writeFlag(key, value) {
75
- try {
76
- localStorage.setItem(key, value ? "1" : "0");
77
- } catch {
78
- // Viewer preferences are best effort when storage is unavailable.
79
- }
80
- if (typeof window !== "undefined") {
81
- window.dispatchEvent(new CustomEvent("cozyclay:preferences-changed", { detail: { key, value } }));
82
- }
83
- }
84
-
85
40
  function PreferenceRow({ title, description, children, testid }) {
86
41
  return (
87
42
  <div className="v2-preferences__row" data-testid={testid}>
@@ -94,10 +49,11 @@ function PreferenceRow({ title, description, children, testid }) {
94
49
  );
95
50
  }
96
51
 
52
+ // A page with one section leaves out its title: the page header already names it.
97
53
  function PreferenceSection({ title, children }) {
98
54
  return (
99
55
  <section className="v2-preferences__section">
100
- <h2 className="v2-preferences__section-title">{title}</h2>
56
+ {title && <h2 className="v2-preferences__section-title">{title}</h2>}
101
57
  <div className="v2-preferences__section-rows">{children}</div>
102
58
  </section>
103
59
  );
@@ -120,43 +76,6 @@ function ToggleControl({ pressed, onChange, label, testid }) {
120
76
  );
121
77
  }
122
78
 
123
- function SelectControl({ value, options, onChange, label, testid }) {
124
- const current = options.indexOf(value);
125
- return (
126
- <button
127
- type="button"
128
- className="v2-preferences__select"
129
- aria-label={label}
130
- data-testid={testid}
131
- onClick={() => onChange(options[(current + 1) % options.length])}
132
- >
133
- <span>{value}</span>
134
- <span className="v2-preferences__select-caret" aria-hidden="true">▾</span>
135
- </button>
136
- );
137
- }
138
-
139
- function RangeControl({ value, min, max, step, label, unit = "", onChange, testid }) {
140
- const percentage = ((value - min) / (max - min)) * 100;
141
- return (
142
- <div className="v2-preferences__range-wrap">
143
- <input
144
- type="range"
145
- className="v2-preferences__range"
146
- min={min}
147
- max={max}
148
- step={step}
149
- value={value}
150
- aria-label={label}
151
- data-testid={testid}
152
- style={{ "--prefs-range-progress": `${percentage}%` }}
153
- onChange={(event) => onChange(Number(event.target.value))}
154
- />
155
- <span className="v2-preferences__range-value">{value}{unit}</span>
156
- </div>
157
- );
158
- }
159
-
160
79
  function ReadonlyHotkeys() {
161
80
  return (
162
81
  <div className="v2-preferences__hotkeys" data-testid="preferences-hotkeys">
@@ -170,40 +89,6 @@ function ReadonlyHotkeys() {
170
89
  );
171
90
  }
172
91
 
173
- function MotionConnection({ state, checking, onRetry }) {
174
- const unavailable = state === "unavailable";
175
- const retryLabel = checking
176
- ? ko("Checking…", "확인 중…")
177
- : unavailable
178
- ? ko("Retry connection", "연결 다시 확인")
179
- : ko("Check connection", "연결 확인");
180
- return (
181
- <div className="v2-preferences__motion-setup" data-testid="motion-setup" data-state={state}>
182
- <div className="v2-preferences__motion-status" data-state={state} role="status" aria-busy={checking}>
183
- <span className="v2-preferences__status-dot" aria-hidden="true" />
184
- <span>{motionReadinessMessage(state)}</span>
185
- </div>
186
- <p>{ko(
187
- "Motion generation is optional. Sample motion, camera editing and exports work without a connection.",
188
- "모션 생성은 선택 사항이에요. 연결 없이도 샘플 모션, 카메라 편집, 내보내기를 쓸 수 있어요.",
189
- )}</p>
190
- <p>{ko(
191
- "Retry checks the local motion bridge without changing the current scene.",
192
- "다시 확인해도 현재 씬은 바뀌지 않고 로컬 모션 브리지 상태만 확인해요.",
193
- )}</p>
194
- <button
195
- type="button"
196
- className="v2-preferences__primary-button"
197
- data-testid="motion-health-retry"
198
- disabled={checking}
199
- onClick={() => onRetry?.()}
200
- >
201
- {retryLabel}
202
- </button>
203
- </div>
204
- );
205
- }
206
-
207
92
  function ThemeControls() {
208
93
  const [theme, setTheme] = useState(readTheme);
209
94
  const options = [
@@ -229,15 +114,7 @@ function ThemeControls() {
229
114
  }
230
115
 
231
116
  function preferenceSection(section, props) {
232
- const {
233
- autoColor, setAutoColor, analyticsOptOut, setAnalyticsOptOutState,
234
- gridView, setGridView, flySpeed, setFlySpeed, sensitivity, setSensitivity,
235
- orbitSelection, setOrbitSelection, invertY, setInvertY, snapping, setSnapping,
236
- ctrlSnap, setCtrlSnap, footLock, setFootLock, bodyContact, setBodyContact,
237
- shading, setShading, gridSize, setGridSize, rotationStep, setRotationStep,
238
- units, setUnits, frameRate, setFrameRate, autosave, setAutosave,
239
- motionState, motionChecking, onRetry, cameraTutorial,
240
- } = props;
117
+ const { autoColor, setAutoColor, analyticsOptOut, setAnalyticsOptOutState, gridView, setGridView, cameraTutorial } = props;
241
118
  const languageControls = (
242
119
  <div className="v2-preferences__language-controls">
243
120
  {LANGUAGES.map((language) => (
@@ -260,7 +137,7 @@ function preferenceSection(section, props) {
260
137
  case "Appearance":
261
138
  return (
262
139
  <>
263
- <PreferenceSection title={ko("Language", "언어")}>
140
+ <PreferenceSection title={ko("Display", "표시")}>
264
141
  <PreferenceRow title={ko("Language", "언어")} description={ko("Choose the labels used throughout the editor.", "에디터에서 사용할 언어를 선택하세요.")}>
265
142
  {languageControls}
266
143
  </PreferenceRow>
@@ -286,119 +163,25 @@ function preferenceSection(section, props) {
286
163
  );
287
164
  case "Viewport":
288
165
  return (
289
- <PreferenceSection title={ko("Viewport", "뷰포트")}>
166
+ <PreferenceSection>
290
167
  <PreferenceRow title={ko("Reference grid", "기준 그리드")} description={ko("Use a dark reference grid instead of the clay deck.", "클레이 데크 대신 어두운 기준 그리드를 사용해요.")}>
291
168
  <ToggleControl pressed={gridView} onChange={(value) => { setGridView(value); writeStoredGridView(globalThis.localStorage, value); }} label={ko("Reference grid", "기준 그리드")} testid="preferences-grid" />
292
169
  </PreferenceRow>
293
- <PreferenceRow title={ko("Shading", "셰이딩")} description={ko("Choose the viewport lighting preview.", "뷰포트 조명 미리보기를 선택하세요.")}>
294
- <SelectControl value={shading} options={[ko("Clay Lit", "클레이 조명"), ko("Solid", "솔리드")]} onChange={setShading} label={ko("Shading mode", "셰이딩 모드")} testid="preferences-shading" />
295
- </PreferenceRow>
296
170
  </PreferenceSection>
297
171
  );
298
- case "Input & Camera":
299
- return (
300
- <>
301
- <PreferenceSection title={ko("Camera", "카메라")}>
302
- <PreferenceRow title={ko("Fly speed", "비행 속도")} description={ko("Right mouse button + WASD", "마우스 오른쪽 버튼 + WASD")}>
303
- <RangeControl value={flySpeed} min={1} max={6} step={1} label={ko("Fly speed", "비행 속도")} onChange={setFlySpeed} testid="preferences-fly-speed" />
304
- </PreferenceRow>
305
- <PreferenceRow title={ko("Mouse sensitivity", "마우스 감도")} description={ko("Pointer movement while looking around.", "둘러볼 때 포인터 이동 감도예요.")}>
306
- <RangeControl value={sensitivity} min={0.1} max={1} step={0.05} label={ko("Mouse sensitivity", "마우스 감도")} onChange={setSensitivity} testid="preferences-sensitivity" />
307
- </PreferenceRow>
308
- <PreferenceRow title={ko("Orbit around selection", "선택 항목 중심으로 회전")} description={ko("Alt-drag keeps the selected item at the pivot.", "Alt를 누르고 드래그하면 선택 항목을 중심으로 돌아요.")}>
309
- <ToggleControl pressed={orbitSelection} onChange={(value) => { setOrbitSelection(value); writeFlag(PREFERENCE_KEYS.orbit, value); }} label={ko("Orbit around selection", "선택 항목 중심으로 회전")} testid="preferences-orbit" />
310
- </PreferenceRow>
311
- <PreferenceRow title={ko("Invert Y", "Y축 반전")} description={ko("Reverse vertical camera movement.", "카메라의 수직 움직임을 반대로 해요.")}>
312
- <ToggleControl pressed={invertY} onChange={(value) => { setInvertY(value); writeFlag(PREFERENCE_KEYS.invertY, value); }} label={ko("Invert Y", "Y축 반전")} testid="preferences-invert-y" />
313
- </PreferenceRow>
314
- </PreferenceSection>
315
- <PreferenceSection title={ko("Snapping", "스냅")}>
316
- <PreferenceRow title={ko("Snapping", "스냅")} description={ko("Keep transforms on the active grid.", "변환을 활성 그리드에 맞춰요.")}>
317
- <ToggleControl pressed={snapping} onChange={(value) => { setSnapping(value); writeFlag(PREFERENCE_KEYS.snap, value); }} label={ko("Snapping", "스냅")} testid="preferences-snapping" />
318
- </PreferenceRow>
319
- <PreferenceRow title={ko("Grid size", "그리드 크기")} description={ko("Stage movement increment.", "스테이지 이동 단위예요.")}>
320
- <SelectControl value={gridSize} options={["10 cm", "25 cm", "50 cm"]} onChange={setGridSize} label={ko("Grid size", "그리드 크기")} testid="preferences-grid-size" />
321
- </PreferenceRow>
322
- <PreferenceRow title={ko("Rotation step", "회전 단위")} description={ko("Stage rotation increment.", "스테이지 회전 단위예요.")}>
323
- <SelectControl value={rotationStep} options={["15°", "30°", "45°"]} onChange={setRotationStep} label={ko("Rotation step", "회전 단위")} testid="preferences-rotation-step" />
324
- </PreferenceRow>
325
- <PreferenceRow title={ko("Ctrl inverts snapping", "Ctrl로 스냅 반전")} description={ko("Hold Ctrl to temporarily reverse snapping.", "Ctrl을 누르면 스냅을 잠시 반대로 적용해요.")}>
326
- <ToggleControl pressed={ctrlSnap} onChange={(value) => { setCtrlSnap(value); writeFlag(PREFERENCE_KEYS.ctrlSnap, value); }} label={ko("Ctrl inverts snapping", "Ctrl로 스냅 반전")} testid="preferences-ctrl-snapping" />
327
- </PreferenceRow>
328
- </PreferenceSection>
329
- <PreferenceSection title={ko("Hotkeys", "단축키")}>
330
- <ReadonlyHotkeys />
331
- </PreferenceSection>
332
- </>
333
- );
334
172
  case "Hotkeys":
335
173
  return (
336
- <PreferenceSection title={ko("Hotkeys", "단축키")}>
174
+ <PreferenceSection>
337
175
  <p className="v2-preferences__section-note">{ko("Shortcuts are read-only here. They stay active whenever focus is outside a text field.", "단축키는 여기서 읽기 전용이에요. 텍스트 입력란 밖에서 항상 사용할 수 있어요.")}</p>
338
176
  <ReadonlyHotkeys />
339
177
  </PreferenceSection>
340
178
  );
341
- case "ARDY Connection":
342
- return (
343
- <PreferenceSection title={ko("ARDY Connection", "ARDY 연결")}>
344
- <PreferenceRow title={ko("Motion setup", "모션 설정")} description={ko("Check today's motion generation route.", "현재 모션 생성 경로를 확인해요.")}>
345
- <span className="v2-preferences__value">{motionReadinessMessage(motionState)}</span>
346
- </PreferenceRow>
347
- <div className="v2-preferences__row v2-preferences__row--full">
348
- <MotionConnection state={motionState} checking={motionChecking} onRetry={onRetry} />
349
- </div>
350
- </PreferenceSection>
351
- );
352
- case "IK Correction":
353
- return (
354
- <PreferenceSection title={ko("IK Correction", "IK 보정")}>
355
- <PreferenceRow title={ko("Foot lock", "발 고정")} description={ko("Keep planted feet stable through the take.", "테이크 전체에서 발을 안정적으로 고정해요.")}>
356
- <ToggleControl pressed={footLock} onChange={(value) => { setFootLock(value); writeFlag(PREFERENCE_KEYS.footLock, value); }} label={ko("Foot lock", "발 고정")} testid="preferences-foot-lock" />
357
- </PreferenceRow>
358
- <PreferenceRow title={ko("Body contact", "신체 접촉")} description={ko("Keep contact points when applying corrections.", "보정을 적용할 때 접촉 지점을 유지해요.")}>
359
- <ToggleControl pressed={bodyContact} onChange={(value) => { setBodyContact(value); writeFlag(PREFERENCE_KEYS.bodyContact, value); }} label={ko("Body contact", "신체 접촉")} testid="preferences-body-contact" />
360
- </PreferenceRow>
361
- </PreferenceSection>
362
- );
363
- case "MCP Server":
364
- return (
365
- <PreferenceSection title={ko("MCP Server", "MCP 서버")}>
366
- <PreferenceRow title={ko("Status", "상태")} description={ko("Agent connections are managed by the running studio.", "에이전트 연결은 실행 중인 스튜디오가 관리해요.")}>
367
- <span className="v2-preferences__status-value"><span className="v2-preferences__status-dot is-muted" aria-hidden="true" />{ko("Not connected", "연결되지 않음")}</span>
368
- </PreferenceRow>
369
- <PreferenceRow title={ko("Port", "포트")} description={ko("The local command endpoint.", "로컬 명령 엔드포인트예요.")}>
370
- <span className="v2-preferences__value v2-preferences__value--mono">8765</span>
371
- </PreferenceRow>
372
- </PreferenceSection>
373
- );
374
- case "Units & Frame rate":
375
- return (
376
- <PreferenceSection title={ko("Units & Frame rate", "단위 및 프레임 레이트")}>
377
- <PreferenceRow title={ko("Units", "단위")} description={ko("Display distances in the inspector.", "인스펙터에서 거리를 표시하는 단위예요.")}>
378
- <SelectControl value={units} options={[ko("Centimeters", "센티미터"), ko("Meters", "미터")]} onChange={setUnits} label={ko("Units", "단위")} testid="preferences-units" />
379
- </PreferenceRow>
380
- <PreferenceRow title={ko("Frame rate", "프레임 레이트")} description={ko("Playback and timeline frame rate.", "재생 및 타임라인 프레임 레이트예요.")}>
381
- <SelectControl value={frameRate} options={["24 fps", "30 fps", "60 fps"]} onChange={setFrameRate} label={ko("Frame rate", "프레임 레이트")} testid="preferences-frame-rate" />
382
- </PreferenceRow>
383
- </PreferenceSection>
384
- );
385
- case "Autosave":
386
- return (
387
- <PreferenceSection title={ko("Autosave", "자동 저장")}>
388
- <PreferenceRow title={ko("Autosave", "자동 저장")} description={ko("Save a project snapshot after an edit settles.", "편집이 끝나면 프로젝트 스냅샷을 저장해요.")}>
389
- <ToggleControl pressed={autosave} onChange={(value) => { setAutosave(value); writeFlag(PREFERENCE_KEYS.autosave, value); }} label={ko("Autosave", "자동 저장")} testid="preferences-autosave" />
390
- </PreferenceRow>
391
- <PreferenceRow title={ko("Interval", "간격")} description={ko("The current editor default.", "현재 에디터 기본값이에요.")}>
392
- <span className="v2-preferences__value">2 min</span>
393
- </PreferenceRow>
394
- </PreferenceSection>
395
- );
396
179
  default:
397
180
  return null;
398
181
  }
399
182
  }
400
183
 
401
- export default function PreferencesDialog({ open, onClose, motionSetup, initialSection = "Input & Camera", cameraTutorial }) {
184
+ export default function PreferencesDialog({ open, onClose, initialSection = "Appearance", cameraTutorial }) {
402
185
  const dialogRef = useRef(null);
403
186
  const searchRef = useRef(null);
404
187
  const closeRef = useRef(onClose);
@@ -408,24 +191,6 @@ export default function PreferencesDialog({ open, onClose, motionSetup, initialS
408
191
  const [analyticsOptOut, setAnalyticsOptOutState] = useState(getAnalyticsOptOut);
409
192
  const [autoColor, setAutoColor] = useState(() => loadAutoColor());
410
193
  const [gridView, setGridView] = useState(() => readStoredGridView(globalThis.localStorage));
411
- const [flySpeed, setFlySpeed] = useState(3);
412
- const [sensitivity, setSensitivity] = useState(0.55);
413
- const [orbitSelection, setOrbitSelection] = useState(() => readFlag(PREFERENCE_KEYS.orbit, true));
414
- const [invertY, setInvertY] = useState(() => readFlag(PREFERENCE_KEYS.invertY));
415
- const [snapping, setSnapping] = useState(() => readFlag(PREFERENCE_KEYS.snap, true));
416
- const [ctrlSnap, setCtrlSnap] = useState(() => readFlag(PREFERENCE_KEYS.ctrlSnap, true));
417
- const [footLock, setFootLock] = useState(() => readFlag(PREFERENCE_KEYS.footLock, true));
418
- const [bodyContact, setBodyContact] = useState(() => readFlag(PREFERENCE_KEYS.bodyContact, true));
419
- const [shading, setShading] = useState(() => ko("Clay Lit", "클레이 조명"));
420
- const [gridSize, setGridSize] = useState("10 cm");
421
- const [rotationStep, setRotationStep] = useState("15°");
422
- const [units, setUnits] = useState(() => ko("Centimeters", "센티미터"));
423
- const [frameRate, setFrameRate] = useState("24 fps");
424
- const [autosave, setAutosave] = useState(() => readFlag(PREFERENCE_KEYS.autosave, true));
425
- const setupProps = motionSetup?.props ?? {};
426
- const motionState = setupProps.state ?? "unavailable";
427
- const motionChecking = setupProps.checking === true;
428
- const onRetry = setupProps.onRetry;
429
194
 
430
195
  const filteredGroups = useMemo(() => {
431
196
  const term = query.trim().toLocaleLowerCase();
@@ -468,16 +233,7 @@ export default function PreferencesDialog({ open, onClose, motionSetup, initialS
468
233
  }, [open, initialSection]);
469
234
 
470
235
  if (!open || typeof document === "undefined") return null;
471
- const currentProps = {
472
- autoColor, setAutoColor, analyticsOptOut,
473
- setAnalyticsOptOutState,
474
- gridView, setGridView, flySpeed, setFlySpeed, sensitivity, setSensitivity,
475
- orbitSelection, setOrbitSelection, invertY, setInvertY, snapping, setSnapping,
476
- ctrlSnap, setCtrlSnap, footLock, setFootLock, bodyContact, setBodyContact,
477
- shading, setShading, gridSize, setGridSize, rotationStep, setRotationStep,
478
- units, setUnits, frameRate, setFrameRate, autosave, setAutosave,
479
- motionState, motionChecking, onRetry, cameraTutorial,
480
- };
236
+ const currentProps = { autoColor, setAutoColor, analyticsOptOut, setAnalyticsOptOutState, gridView, setGridView, cameraTutorial };
481
237
 
482
238
  return createPortal(
483
239
  <div className="v2-preferences" data-testid="preferences-dialog-backdrop" onPointerDown={(event) => { if (event.target === event.currentTarget) closeRef.current?.(); }}>
@@ -520,12 +276,7 @@ export default function PreferencesDialog({ open, onClose, motionSetup, initialS
520
276
  </aside>
521
277
  <main className="v2-preferences__content">
522
278
  <header className="v2-preferences__content-header">
523
- <h1 id="v2-preferences-title">{ko(activeSection, activeSection)}</h1>
524
- <button type="button" className="v2-preferences__reset" data-testid="preferences-reset" onClick={() => {
525
- setFlySpeed(3); setSensitivity(0.55); setOrbitSelection(true); setInvertY(false); setSnapping(true); setCtrlSnap(true);
526
- setShading(ko("Clay Lit", "클레이 조명")); setGridSize("10 cm"); setRotationStep("15°"); setUnits(ko("Centimeters", "센티미터")); setFrameRate("24 fps"); setAutosave(true);
527
- writeFlag(PREFERENCE_KEYS.orbit, true); writeFlag(PREFERENCE_KEYS.invertY, false); writeFlag(PREFERENCE_KEYS.snap, true); writeFlag(PREFERENCE_KEYS.ctrlSnap, true); writeFlag(PREFERENCE_KEYS.autosave, true);
528
- }}>{ko("Reset to defaults", "기본값으로 재설정")}</button>
279
+ <h1 id="v2-preferences-title">{NAV_LABELS[activeSection] ?? activeSection}</h1>
529
280
  </header>
530
281
  <div className="v2-preferences__content-scroll">
531
282
  {preferenceSection(activeSection, currentProps)}
@@ -1,7 +1,6 @@
1
1
  import { useEffect, useRef } from "react";
2
2
  import { flushSync } from "react-dom";
3
3
  import SettingsMenu from "../settings-menu.jsx";
4
- import { MotionSetup } from "../motion-readiness-ui.jsx";
5
4
  import { useStudioShell } from "./studio-shell-context.js";
6
5
 
7
6
  // Temporary adapter until the Preferences region replaces SettingsMenu.
@@ -10,9 +9,7 @@ import { useStudioShell } from "./studio-shell-context.js";
10
9
  // the shell context, without mounting a second copy or changing SettingsMenu.
11
10
  export default function PreferencesSlot() {
12
11
  const {
13
- preferencesOpen, setPreferencesOpen, motionSetupReveal, motionSetupKind,
14
- trailReadinessState, lineReadinessState, readinessState, bridgeChecking,
15
- recheckMotionHealth,
12
+ preferencesOpen, setPreferencesOpen,
16
13
  } = useStudioShell();
17
14
  const hostRef = useRef(null);
18
15
  useEffect(() => {
@@ -31,10 +28,7 @@ export default function PreferencesSlot() {
31
28
  }, [preferencesOpen]);
32
29
  return (
33
30
  <div className="preferences-slot" ref={hostRef}>
34
- <SettingsMenu
35
- motionSetupReveal={motionSetupReveal}
36
- motionSetup={<MotionSetup state={motionSetupKind === "trail" ? trailReadinessState : motionSetupKind === "line" ? lineReadinessState : readinessState} checking={bridgeChecking} onRetry={recheckMotionHealth} />}
37
- />
31
+ <SettingsMenu />
38
32
  </div>
39
33
  );
40
34
  }
@@ -0,0 +1,17 @@
1
+ import { useLayoutEffect, useState } from "react";
2
+ import { createPortal } from "react-dom";
3
+
4
+ export default function ShotPreviewHeader({ name, lens }) {
5
+ const [host, setHost] = useState(null);
6
+ useLayoutEffect(() => {
7
+ setHost(document.querySelector(".vp-shot-preview .vp-shot-preview-tag"));
8
+ }, []);
9
+ if (!host) return null;
10
+ return createPortal(
11
+ <span className="vp-shot-preview-meta" data-testid="shot-preview-header">
12
+ <span className="vp-shot-preview-name">{name}</span>
13
+ <span className="vp-shot-preview-lens">{lens}</span>
14
+ </span>,
15
+ host,
16
+ );
17
+ }
@@ -1,16 +1,15 @@
1
- import { useRef, useState } from "react";
2
1
  import { useStudioShell } from "./studio-shell-context.js";
3
2
  import ProjectPanel from "../panels/ProjectPanel.jsx";
4
- import MenuBar, { MenuPopover } from "./MenuBar.jsx";
3
+ import MenuBar from "./MenuBar.jsx";
5
4
  import { SaveState } from "./StatusBar.jsx";
6
- import { ko, isKo } from "../locale.js";
5
+ import { ko } from "../locale.js";
7
6
  import "./topbar.css";
8
7
 
9
- // 2a top bar: File/Edit/Window/Help, then only the MCP state and the one
10
- // primary action. Save and Export live in File (G7). #570: the project name
8
+ // 2a top bar: File/Edit/Window/Help, then the MCP state. Motion is authored by the
9
+ // agent (motion.compile), so there is no generate button. Save and Export live in File (G7). #570: the project name
11
10
  // and its save state head the left column (ProjectHead below).
12
11
  export default function TopBar({ preferences }) {
13
- const { recState, liveHubStatus, liveWorkspaceHandle, previsMode } = useStudioShell();
12
+ const { recState, liveHubStatus, liveWorkspaceHandle } = useStudioShell();
14
13
  const connected = liveHubStatus === "connected";
15
14
  return (
16
15
  <header className="topbar v2-topbar" data-rec-state={recState}>
@@ -25,7 +24,6 @@ export default function TopBar({ preferences }) {
25
24
  <i className="topbar-mcp-dot" aria-hidden="true" />
26
25
  <span className="topbar-mcp-text">{connected ? ko("MCP connected", "MCP 연결됨") : ko("MCP offline", "MCP 꺼짐")}</span>
27
26
  </span>
28
- {previsMode !== "storyboard" && <GenerateMotion />}
29
27
  </header>
30
28
  );
31
29
  }
@@ -65,79 +63,3 @@ function PrevisModeBadge({ mode }) {
65
63
  </span>
66
64
  );
67
65
  }
68
-
69
- // "Generate Motion" is today's Scene generate (G6) and the one home for
70
- // generation (IS-2): with authored prompt blocks it runs them all, as the
71
- // removed Details "Generate all blocks" did; otherwise it runs the prompt.
72
- // The caret holds the take bar's Scene actions; a refused action says why in
73
- // place and in a toast (R3).
74
- function GenerateMotion() {
75
- const {
76
- runArdy, sceneGenerateDisabledReason, sceneAgainDisabledReason, runSceneAgain,
77
- addSceneBlock, tlFrame, setToast, ardyRunning, promptClips, runStudioAction,
78
- } = useStudioShell();
79
- const hasBlocks = promptClips.some((clip) => clip.text.trim());
80
- const [open, setOpen] = useState(false);
81
- const caretRef = useRef(null);
82
- const reason = sceneGenerateDisabledReason();
83
- const actions = [
84
- { id: "new", label: ko("Start over", "새로 만들기"), reason, run: () => runArdy({ fresh: true }) },
85
- { id: "again", label: ko("Take it again", "다시 뽑기"), reason: sceneAgainDisabledReason(), run: runSceneAgain },
86
- { id: "block", label: isKo ? `프레임 ${tlFrame}에 블록 추가` : `Add block at frame ${tlFrame}`, reason: "", run: addSceneBlock },
87
- ];
88
- return (
89
- <div className="topbar-generate" role="group" aria-label={ko("Generate Motion", "모션 생성")}>
90
- <button
91
- type="button"
92
- className="topbar-generate-main"
93
- data-testid="topbar-generate"
94
- aria-disabled={reason ? "true" : undefined}
95
- data-disabled-reason={reason || undefined}
96
- title={reason || ko("Generate motion from the prompt and blocks", "프롬프트와 블록으로 모션을 생성합니다")}
97
- onClick={() => (reason ? setToast(reason) : hasBlocks ? runStudioAction("motion.generateAllBlocks") : runArdy())}
98
- >
99
- {ardyRunning ? ko("Generating…", "생성 중…") : (
100
- <>
101
- <span className="topbar-generate-full">{ko("Generate Motion", "모션 생성")}</span>
102
- <span className="topbar-generate-short">{ko("Generate", "생성")}</span>
103
- </>
104
- )}
105
- </button>
106
- <button
107
- type="button"
108
- className="topbar-generate-caret"
109
- data-testid="topbar-generate-menu"
110
- ref={caretRef}
111
- aria-haspopup="menu"
112
- aria-expanded={open}
113
- aria-label={ko("More generate actions", "생성 작업 더 보기")}
114
- onClick={() => setOpen((value) => !value)}
115
- >
116
- <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 9l6 6 6-6" /></svg>
117
- </button>
118
- {open && (
119
- <MenuPopover anchorRef={caretRef} align="end" onClose={() => setOpen(false)} label={ko("Generate actions", "생성 작업")}>
120
- {actions.map((action) => (
121
- <button
122
- type="button"
123
- role="menuitem"
124
- key={action.id}
125
- className="menubar-item"
126
- data-generate-action={action.id}
127
- aria-disabled={action.reason ? "true" : undefined}
128
- data-disabled-reason={action.reason || undefined}
129
- onClick={() => {
130
- setOpen(false);
131
- if (action.reason) setToast(action.reason);
132
- else action.run();
133
- }}
134
- >
135
- <span className="menubar-item-label">{action.label}</span>
136
- {action.reason && <small className="menubar-item-reason">{action.reason}</small>}
137
- </button>
138
- ))}
139
- </MenuPopover>
140
- )}
141
- </div>
142
- );
143
- }