cozyclay 2.1.1 → 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.
- package/CHANGELOG.md +60 -0
- package/README.md +12 -30
- package/bin/agent/agent-routes.mjs +40 -113
- package/bin/agent/agent-runner.mjs +9 -10
- package/bin/agent/cliproxy-provider.mjs +135 -0
- package/bin/agent/credential-store.mjs +30 -7
- package/bin/agent/pi-tools.mjs +4 -1
- package/bin/agent/provider-keys.mjs +32 -0
- package/bin/agent/provider-login.mjs +110 -0
- package/bin/agent/provider-routes.mjs +99 -0
- package/bin/agent/providers.mjs +19 -97
- package/bin/agent/script-tool.mjs +17 -4
- package/bin/agent/studio-motion-reference.mjs +23 -0
- package/bin/agent/studio-prompt.mjs +1 -1
- package/bin/agent/studio-rebase-text.mjs +32 -0
- package/bin/agent/studio-rebase.mjs +26 -39
- package/bin/agent/studio-tools.mjs +9 -28
- package/bin/agent/tool-arguments.mjs +49 -0
- package/bin/agent/turn-frames.mjs +66 -0
- package/bin/codex-auth.mjs +9 -2
- package/bin/cozyclay.mjs +10 -116
- package/bin/live/cli.mjs +3 -3
- package/bin/mcp-runtime.mjs +2 -12
- package/bin/package-signature.mjs +0 -4
- package/dist/app/index.html +7 -6
- package/dist/assets/EXRLoader-CvVIvGVE.js +1 -0
- package/dist/assets/analytics-C9sUnndd.js +1 -0
- package/dist/assets/app-CCh--1Hc.js +5087 -0
- package/dist/assets/app-f-fkV5uP.css +1 -0
- package/dist/assets/compile-worker-CkxiD6lH.js +5 -0
- package/dist/assets/fflate.module-KbGj5-H6.js +5 -0
- package/dist/assets/{first-shot-handoff-msLI71g1.js → first-shot-handoff-CC4xe4HM.js} +1 -1
- package/dist/assets/{landing-ChUvB_zL.js → landing-DjHD8u7k.js} +1 -1
- package/dist/assets/scene-asset-sync-Hx_FzdOH.js +20 -0
- package/dist/assets/scene-asset-sync-_S8NQl5B.css +1 -0
- package/dist/assets/workflow-C4yKH1p4.js +179 -0
- package/dist/cozyclay-package.json +1 -1
- package/dist/index.html +3 -3
- package/dist/sw.js +3 -6
- package/dist/workflow/index.html +5 -4
- package/mcp/LIVE-PROTOCOL.md +7 -47
- package/mcp/README.md +16 -26
- package/mcp/live-hub.mjs +6 -10
- package/mcp/package.json +1 -3
- package/mcp/tool-handlers.mjs +4 -168
- package/package.json +3 -22
- package/src/App.jsx +150 -2624
- package/src/agent-progress.js +79 -0
- package/src/agent-turn-mark.js +30 -0
- package/src/analytics.js +1 -19
- package/src/app-context.js +5 -0
- package/src/app-stage.jsx +2 -34
- package/src/asset-pane.jsx +6 -5
- package/src/camera-block.js +21 -0
- package/src/camera-direction.js +120 -0
- package/src/character-kind.js +3 -9
- package/src/command-bus.js +8 -6
- package/src/commands/cast.js +5 -34
- package/src/commands/elements/character.js +1 -1
- package/src/commands/elements/motion.js +1 -6
- package/src/commands/elements/object.js +6 -2
- package/src/commands/elements/shot.js +4 -1
- package/src/commands/elements.js +38 -14
- package/src/commands/index.js +3 -1
- package/src/commands/kits.js +37 -0
- package/src/commands/motion-timing.js +57 -0
- package/src/commands/motion.js +9 -152
- package/src/commands/motion3-compile.js +65 -0
- package/src/commands/motion3.js +207 -0
- package/src/commands/objects.js +6 -4
- package/src/commands/shot.js +49 -11
- package/src/commands/stage.js +14 -1
- package/src/commands/view.js +4 -1
- package/src/document-mirrors.js +42 -0
- package/src/document-store.js +4 -0
- package/src/domains/cast.js +19 -194
- package/src/domains/motion/motion-range-pin-rules.js +1 -1
- package/src/domains/motion/take-source.js +51 -0
- package/src/domains/motion.js +60 -1838
- package/src/domains/scenes.js +12 -55
- package/src/domains/shots.js +2 -2
- package/src/domains/stage.js +4 -2
- package/src/draft-ghost.js +46 -0
- package/src/draft-ghost.jsx +129 -0
- package/src/dualview.jsx +4 -3
- package/src/effects/EffectsLayer.jsx +112 -0
- package/src/effects/effect-meshes.js +232 -0
- package/src/effects/effect-record.js +103 -0
- package/src/effects/emitter.js +59 -0
- package/src/effects/simulate.js +261 -0
- package/src/effects/state.js +59 -0
- package/src/execution-telemetry.js +2 -3
- package/src/first-success-guide.jsx +5 -5
- package/src/ghost-set.js +257 -0
- package/src/held-object-edit.jsx +113 -0
- package/src/held-object-pose.js +175 -0
- package/src/hierarchy-model.js +1 -1
- package/src/hierarchy-panel.jsx +1 -1
- package/src/imported-mesh.jsx +103 -0
- package/src/kits/held.js +84 -0
- package/src/kits/index.js +70 -0
- package/src/kits/smoking.js +57 -0
- package/src/light-blockers.js +93 -0
- package/src/motion/beat-board-model.js +84 -0
- package/src/motion/beat-board.css +124 -0
- package/src/motion/beat-board.jsx +59 -0
- package/src/motion/center-of-mass.js +66 -0
- package/src/motion/fix-collisions.js +850 -0
- package/src/motion/physics-review.js +118 -0
- package/src/{ardy → motion}/physics-support.js +1 -76
- package/src/motion/rig-snapshot.js +22 -0
- package/src/motion/take-segments.jsx +140 -0
- package/src/{ardy → motion}/timeline-coordinates.js +0 -21
- package/src/{ardy → motion}/timeline.css +1 -2
- package/src/{ardy → motion}/timeline.jsx +42 -413
- package/src/motion/waypoints.js +76 -0
- package/src/motion3/beats.js +83 -0
- package/src/motion3/body.js +158 -0
- package/src/motion3/bones.js +47 -0
- package/src/motion3/carried.js +47 -0
- package/src/motion3/compile-job.js +75 -0
- package/src/motion3/compile-worker.js +10 -0
- package/src/motion3/compiler/anchors.js +105 -0
- package/src/motion3/compiler/arm-orient.js +128 -0
- package/src/motion3/compiler/channels.js +125 -0
- package/src/motion3/compiler/compile.js +205 -0
- package/src/motion3/compiler/gait-rhythm.js +97 -0
- package/src/motion3/compiler/grip.js +171 -0
- package/src/motion3/compiler/head-steady.js +48 -0
- package/src/motion3/compiler/hold.js +134 -0
- package/src/motion3/compiler/idle.js +113 -0
- package/src/motion3/compiler/limbs.js +170 -0
- package/src/motion3/compiler/math.js +72 -0
- package/src/motion3/compiler/pose.js +162 -0
- package/src/motion3/compiler/quat.js +49 -0
- package/src/motion3/compiler/skeleton.js +74 -0
- package/src/motion3/compiler/validate-common.js +32 -0
- package/src/motion3/compiler/validate-goals.js +118 -0
- package/src/motion3/compiler/validate-objects.js +143 -0
- package/src/motion3/compiler/validate-parts.js +116 -0
- package/src/motion3/compiler/validate.js +122 -0
- package/src/motion3/compiler/vocab.js +73 -0
- package/src/motion3/compiler/walk-pelvis.js +275 -0
- package/src/motion3/compiler/walk.js +207 -0
- package/src/motion3/compiler/wrist-clamp.js +32 -0
- package/src/motion3/delta.js +47 -0
- package/src/motion3/describe.js +174 -0
- package/src/motion3/docs.js +27 -0
- package/src/motion3/edit-carry.js +21 -0
- package/src/motion3/fix/ease.js +16 -0
- package/src/motion3/fix/ground.js +37 -0
- package/src/motion3/fix/index.js +52 -0
- package/src/motion3/fix/push.js +71 -0
- package/src/motion3/fix/reach.js +46 -0
- package/src/motion3/fix/retime.js +79 -0
- package/src/motion3/fix/self.js +211 -0
- package/src/motion3/fix/slide.js +70 -0
- package/src/motion3/fix/turn.js +51 -0
- package/src/motion3/follow.js +39 -0
- package/src/motion3/free-motion.js +173 -0
- package/src/motion3/grip-choice.js +130 -0
- package/src/motion3/hold-plan.js +157 -0
- package/src/motion3/json-patch.js +77 -0
- package/src/motion3/key-aim.js +105 -0
- package/src/motion3/key-edit.js +82 -0
- package/src/motion3/lenient.js +127 -0
- package/src/motion3/object-keys.js +236 -0
- package/src/motion3/object-pose.js +182 -0
- package/src/motion3/object-tracks.js +12 -0
- package/src/motion3/pipeline.js +102 -0
- package/src/motion3/playback.js +51 -0
- package/src/motion3/probes.js +91 -0
- package/src/motion3/qa/body-checks.js +34 -0
- package/src/motion3/qa/check-names.js +14 -0
- package/src/motion3/qa/checks.js +121 -0
- package/src/motion3/qa/contact-checks.js +51 -0
- package/src/motion3/qa/explain.js +80 -0
- package/src/motion3/qa/fmt.js +5 -0
- package/src/motion3/qa/foot-checks.js +72 -0
- package/src/motion3/qa/geometry.js +77 -0
- package/src/motion3/qa/goals.js +191 -0
- package/src/motion3/qa/ground.js +60 -0
- package/src/motion3/qa/hints-contact.js +179 -0
- package/src/motion3/qa/hints-goal.js +160 -0
- package/src/motion3/qa/hints-knee.js +24 -0
- package/src/motion3/qa/hints-motion.js +209 -0
- package/src/motion3/qa/hints-object.js +91 -0
- package/src/motion3/qa/index.js +42 -0
- package/src/motion3/qa/key-checks.js +82 -0
- package/src/motion3/qa/near.js +96 -0
- package/src/motion3/qa/object-checks.js +135 -0
- package/src/motion3/qa/patch.js +161 -0
- package/src/motion3/qa/severity.js +38 -0
- package/src/motion3/qa/spec-checks.js +65 -0
- package/src/motion3/qa/style.js +218 -0
- package/src/motion3/qa/wrist-checks.js +69 -0
- package/src/motion3/qa/wrist-obs.js +60 -0
- package/src/motion3/refs.js +120 -0
- package/src/motion3/repair-tune.js +121 -0
- package/src/motion3/repair.js +83 -0
- package/src/motion3/report.js +67 -0
- package/src/motion3/rigs/index.js +14 -0
- package/src/motion3/rigs/x-bot-tpose-body.json +1 -0
- package/src/motion3/rigs/x-bot-tpose.json +1 -0
- package/src/motion3/rigs/y-bot-tpose-body.json +1 -0
- package/src/motion3/rigs/y-bot-tpose.json +1 -0
- package/src/motion3/scene.js +60 -0
- package/src/motion3/schema/brief.js +89 -0
- package/src/motion3/schema/fields.js +44 -0
- package/src/motion3/schema/spec-examples.js +46 -0
- package/src/motion3/schema/topics.js +111 -0
- package/src/motion3/schema/types.js +147 -0
- package/src/motion3/search.js +117 -0
- package/src/motion3/second-hand.js +112 -0
- package/src/motion3/skills/basic.js +82 -0
- package/src/motion3/skills/book.js +76 -0
- package/src/motion3/skills/car.js +145 -0
- package/src/motion3/skills/frames-auto.js +29 -0
- package/src/motion3/skills/index.js +83 -0
- package/src/motion3/skills/info.js +65 -0
- package/src/motion3/skills/smoke-kit.js +109 -0
- package/src/motion3/skills/smoke.js +160 -0
- package/src/motion3/spec-store.js +59 -0
- package/src/motion3/take-edit.js +155 -0
- package/src/motion3/take.js +63 -0
- package/src/motion3/timeline.js +127 -0
- package/src/motion3/views.js +121 -0
- package/src/motion3/walk-plan.js +119 -0
- package/src/object-catalog.jsx +7 -1
- package/src/object-colors.js +98 -0
- package/src/object-gizmo-parts.js +115 -0
- package/src/object-gizmo.jsx +37 -122
- package/src/object-glow.js +139 -0
- package/src/object-hidden.js +33 -0
- package/src/object-look.js +196 -0
- package/src/object-size.js +10 -0
- package/src/object-travel.js +71 -6
- package/src/panels/CameraPanel.jsx +7 -7
- package/src/panels/HdrEnvironmentControls.jsx +59 -0
- package/src/panels/LightPanel.jsx +25 -4
- package/src/panels/ObjectLookPanel.jsx +88 -0
- package/src/panels/PosePanel.jsx +2 -17
- package/src/panels/RigControlPanel.jsx +5 -53
- package/src/panels/SubjectBox.jsx +4 -1
- package/src/panels/details.css +14 -0
- package/src/posestudio.jsx +4 -27
- package/src/project-browser.jsx +3 -4
- package/src/project-resources.js +18 -31
- package/src/project.js +13 -104
- package/src/props.jsx +25 -280
- package/src/rail-dot-drag.js +23 -0
- package/src/render-passes.js +10 -0
- package/src/resource-status.jsx +1 -0
- package/src/result-modal.jsx +4 -19
- package/src/room.jsx +20 -12
- package/src/scene-assets.js +8 -6
- package/src/scene-light-place.js +72 -0
- package/src/scene-lights.jsx +148 -0
- package/src/scene-objects.js +31 -139
- package/src/scenes.js +15 -105
- package/src/semantic-edit.js +2 -5
- package/src/set-pieces.jsx +183 -0
- package/src/settings-menu.jsx +3 -11
- package/src/shell/BottomDock.jsx +9 -51
- package/src/shell/DetailsSlot.jsx +16 -200
- package/src/shell/GhostsMenuGroup.jsx +74 -0
- package/src/shell/LibrarySlot.jsx +1 -3
- package/src/shell/MenuBar.jsx +3 -3
- package/src/shell/PreferencesDialog.jsx +15 -264
- package/src/shell/PreferencesSlot.jsx +2 -8
- package/src/shell/TopBar.jsx +5 -84
- package/src/shell/ViewportToolbar.jsx +10 -70
- package/src/shell/agent-glass.css +19 -6
- package/src/shell/details-selection.js +42 -0
- package/src/shell/ghosts-menu.css +22 -0
- package/src/shell/glass-regions.css +29 -3
- package/src/shell/preferences.css +6 -1
- package/src/shot-authoring.js +4 -7
- package/src/soft-shadows.js +37 -0
- package/src/stage-attach-frames.js +12 -12
- package/src/stage-canvas-rigs.jsx +3 -3
- package/src/stage-capture.jsx +42 -8
- package/src/stage-characters.jsx +22 -216
- package/src/stage-editor-gizmos.jsx +6 -6
- package/src/stage-environment.js +93 -0
- package/src/stage-hdr-builtins.js +107 -0
- package/src/stage-hdr-image.js +116 -0
- package/src/stage-hdr-library.js +70 -0
- package/src/stage-hdr-map.js +94 -0
- package/src/stage-hdr.js +130 -0
- package/src/stage-lighting.js +149 -0
- package/src/stage-occlusion.js +210 -0
- package/src/stage-sky.jsx +159 -0
- package/src/stage-startup-defaults.js +5 -9
- package/src/studio-actions.js +12 -14
- package/src/studio-agent-commands.js +19 -16
- package/src/studio-agent-motion.js +9 -9
- package/src/studio-agent-protocol.js +41 -71
- package/src/studio-app-binding.js +25 -45
- package/src/studio-asset-list.js +17 -0
- package/src/studio-contact-sheet.js +37 -5
- package/src/studio-elements.js +27 -7
- package/src/studio-entity-bounds.js +18 -0
- package/src/studio-error-codes.js +8 -0
- package/src/studio-export-framing.js +152 -0
- package/src/studio-lighting-check.js +103 -0
- package/src/studio-motion-visual.js +150 -0
- package/src/studio-schema-errors.js +80 -0
- package/src/studio-support-gap.js +74 -0
- package/src/styles.css +1 -19
- package/src/timeline-defaults.js +5 -0
- package/src/timeline-extent.js +8 -20
- package/src/tutorial-walk.js +17 -0
- package/src/ui-scrub.js +1 -1
- package/src/use-shot-camera-tracks.js +12 -0
- package/src/view-ghosts.js +97 -0
- package/src/view-ghosts.jsx +49 -0
- package/src/workflow/AgentPanel.jsx +47 -166
- package/src/workflow/AgentProgressCard.jsx +107 -0
- package/src/workflow/AgentReplyText.jsx +37 -0
- package/src/workflow/AgentTurnSteps.jsx +84 -0
- package/src/workflow/LoginPanel.jsx +140 -0
- package/src/workflow/WorkflowBuilder.jsx +7 -23
- package/src/workflow/agent-client.js +54 -51
- package/src/workflow/agent-panel.css +71 -1
- package/src/workflow/agent-progress-card.css +167 -0
- package/src/workflow/agent-progress-view.js +47 -0
- package/src/workflow/agent-turn-steps.css +113 -0
- package/src/workflow/agent-turn.js +191 -0
- package/src/workflow/login-client.js +34 -0
- package/src/workflow/motion-input.js +18 -31
- package/src/workflow/node-schema.js +1 -1
- package/src/workflow/reply-markdown.js +69 -0
- package/src/workflow/scene-asset-sync.js +8 -8
- package/tools/agent-session-stats.mjs +61 -0
- package/tools/dev-full.mjs +5 -56
- package/tools/eslint-baseline.json +12 -13
- package/tools/knip-baseline.json +0 -179
- package/tools/loc-baseline.json +31 -81
- package/tools/motion3/extract-body.mjs +103 -0
- package/tools/motion3/extract-rig.mjs +85 -0
- package/tools/process-supervisor.mjs +0 -88
- package/tools/run-tests.mjs +8 -124
- package/bin/agent/motion-runtime.mjs +0 -76
- package/dist/ardy/cskel27-rest.json +0 -557
- package/dist/assets/analytics-C9pMpW7s.js +0 -1
- package/dist/assets/app-B_2XB9rw.css +0 -1
- package/dist/assets/app-DAuvKPP8.js +0 -4920
- package/dist/assets/config-Bx7pYsD9.js +0 -1
- package/dist/assets/config-DeoFTYzb.css +0 -1
- package/dist/assets/demo-CvKuBgy5.js +0 -1
- package/dist/assets/scene-asset-sync-DKkpjKBV.js +0 -19
- package/dist/assets/scene-asset-sync-DjJ_cJ2R.css +0 -1
- package/dist/assets/ticket-BPk2Ni95.js +0 -1
- package/dist/assets/workflow-jJRBR94Z.js +0 -179
- package/dist/demo/walk-then-stop.npz +0 -0
- package/mcp/ardy-prompts.mjs +0 -218
- package/src/ardy/auto-fix-panel.css +0 -108
- package/src/ardy/auto-physics.js +0 -1194
- package/src/ardy/client.js +0 -153
- package/src/ardy/convert.js +0 -313
- package/src/ardy/cskel27-neutral.js +0 -39
- package/src/ardy/cskel27.js +0 -77
- package/src/ardy/export.js +0 -165
- package/src/ardy/fix-collisions.js +0 -2257
- package/src/ardy/foot-lock.js +0 -230
- package/src/ardy/motion-calibration.js +0 -118
- package/src/ardy/motion-edit.js +0 -213
- package/src/ardy/motion-url.js +0 -55
- package/src/ardy/mp4-duration.js +0 -102
- package/src/ardy/npz.js +0 -595
- package/src/ardy/physics-panel.css +0 -21
- package/src/ardy/physics-panel.jsx +0 -89
- package/src/ardy/physics-refine.js +0 -111
- package/src/ardy/physics-review.js +0 -567
- package/src/ardy/physics-temporal.js +0 -54
- package/src/ardy/platform-fit-panel.css +0 -64
- package/src/ardy/platform-fit-panel.jsx +0 -41
- package/src/ardy/platform-fit.js +0 -326
- package/src/ardy/playback.js +0 -711
- package/src/ardy/pose-pin.js +0 -97
- package/src/ardy/prompt-clips.js +0 -30
- package/src/ardy/retime.js +0 -211
- package/src/ardy/root-drop.js +0 -369
- package/src/ardy/timeline-resize.js +0 -13
- package/src/ardy/to-cskel27.js +0 -225
- package/src/ardy/trim.js +0 -33
- package/src/ardy/waypoints.js +0 -369
- package/src/ardy-bridge-contract.js +0 -281
- package/src/domains/motion/motion-video-capture.js +0 -664
- package/src/i2v-motion-client.js +0 -77
- package/src/i2v-motion-studio.jsx +0 -180
- package/src/line-edit.js +0 -1348
- package/src/motion/generation.js +0 -105
- package/src/motion-readiness-ui.jsx +0 -67
- package/src/motion-readiness.js +0 -40
- package/src/motion-resources.js +0 -177
- package/src/motion-store.js +0 -65
- package/src/motion-trail.js +0 -601
- package/src/multimodel-ingest.js +0 -394
- package/src/panels/PromptBlocksPanel.jsx +0 -444
- package/src/panels/VideoCapturePanel.jsx +0 -181
- package/src/pose-extract/browser.js +0 -42
- package/src/pose-extract/detector.js +0 -100
- package/src/pose-extract/fit.js +0 -227
- package/src/pose-extract/image-frame.js +0 -51
- package/src/pose-extract/index.js +0 -58
- package/src/pose-extract/keyframes.js +0 -74
- package/src/pose-extract/landmarks.js +0 -162
- package/src/pose-extract/mirror.js +0 -153
- package/src/pose-extract/take.js +0 -131
- package/src/pose-extract/video-frames.js +0 -91
- package/src/take-recipe.js +0 -165
- package/src/trail-key-conflicts.js +0 -39
- package/src/trail-pick.js +0 -59
- package/src/use-i2v-capture-modal.js +0 -15
- package/tools/ardy/BRIDGE.md +0 -37
- package/tools/ardy/GVHMR-NPZ.md +0 -68
- package/tools/ardy/README.md +0 -124
- package/tools/ardy/__pycache__/cclay_gvhmr_worker.cpython-313.pyc +0 -0
- package/tools/ardy/artifacts.mjs +0 -34
- package/tools/ardy/bridge.mjs +0 -1732
- package/tools/ardy/bvh-cskel27.mjs +0 -1265
- package/tools/ardy/cclay_constrained_generate.py +0 -561
- package/tools/ardy/cclay_gvhmr_worker.py +0 -264
- package/tools/ardy/cclay_motion_edit.py +0 -510
- package/tools/ardy/cclay_sequence_generate.py +0 -705
- package/tools/ardy/cclay_worker.py +0 -304
- package/tools/ardy/dump-npz.py +0 -205
- package/tools/ardy/extract-rest.mjs +0 -299
- package/tools/ardy/extract.mjs +0 -507
- package/tools/ardy/footage.mjs +0 -467
- package/tools/ardy/gvhmr-floor.mjs +0 -102
- package/tools/ardy/gvhmr-to-cskel27.mjs +0 -21
- package/tools/ardy/gvhmr_fastpath.py +0 -168
- package/tools/ardy/gvhmr_trajectory.py +0 -240
- package/tools/ardy/merge-text-encoder.py +0 -160
- package/tools/ardy/mocap-metrics.mjs +0 -200
- package/tools/ardy/mocap-quality-gate.mjs +0 -110
- package/tools/ardy/motion-stabilize.mjs +0 -348
- package/tools/ardy/npz.mjs +0 -414
- package/tools/ardy/pose-to-npz.mjs +0 -106
- package/tools/ardy/prompt-limits.mjs +0 -5
- package/tools/ardy/run-edit-on-box.sh +0 -73
- package/tools/ardy/run-local.mjs +0 -233
- package/tools/ardy/run-on-box.sh +0 -593
- package/tools/ardy/run-sequence-on-box.sh +0 -177
- package/tools/ardy/runners/gvhmr-worker.mjs +0 -206
- package/tools/ardy/runners/index.mjs +0 -18
- package/tools/ardy/runners/local.mjs +0 -455
- package/tools/ardy/runners/proc.mjs +0 -125
- package/tools/ardy/runners/remote.mjs +0 -252
- package/tools/ardy/setup-local.mjs +0 -189
- package/tools/ardy/setup-text-encoder-on-box.sh +0 -93
- package/tools/ardy/setup-text-encoder.py +0 -306
- package/tools/ardy/smpl-cskel27.mjs +0 -178
- package/tools/ardy/visual-qa.mjs +0 -196
- package/tools/ardy/vq-car.mjs +0 -52
- package/tools/bench/EXP3.md +0 -61
- package/tools/bench/cclay_bench_extract_incam.py +0 -125
- package/tools/bench/cclay_bench_extract_obs.py +0 -204
- package/tools/bench/cclay_bench_runner.py +0 -42
- package/tools/bench/cube-contact.mjs +0 -162
- package/tools/bench/exp3.mjs +0 -152
- package/tools/bench/extract-bench-lib.mjs +0 -216
- package/tools/bench/extract-bench.mjs +0 -302
- package/tools/bench/fal-generate.mjs +0 -88
- package/tools/bench/fit/README.md +0 -189
- package/tools/bench/fit/camera.mjs +0 -59
- package/tools/bench/fit/contact.mjs +0 -419
- package/tools/bench/fit/footlock.mjs +0 -234
- package/tools/bench/fit/motion.mjs +0 -85
- package/tools/bench/fit/pin.mjs +0 -27
- package/tools/bench/fit/remote.mjs +0 -105
- package/tools/bench/fit-bench.mjs +0 -126
- package/tools/bench/fit-sanity.mjs +0 -45
- package/tools/bench/metrics.mjs +0 -313
- package/tools/bench/obs/depth.mjs +0 -258
- package/tools/bench/obs/extrinsics.mjs +0 -175
- package/tools/bench/obs/fit_mannequin_betas.py +0 -340
- package/tools/bench/obs/ground.mjs +0 -294
- package/tools/bench/obs/heading.mjs +0 -151
- package/tools/bench/obs/ladder.mjs +0 -555
- package/tools/bench/obs/mannequin-betas.json +0 -124
- package/tools/bench/obs/remote.mjs +0 -83
- package/tools/bench/obs/rest_joints.py +0 -52
- package/tools/bench/obs/ybot-targets.mjs +0 -49
- package/tools/bench/obs-bench.mjs +0 -520
- package/tools/bench/score.mjs +0 -343
- package/tools/bench/summarize.mjs +0 -86
- package/tools/demo-worker/README.md +0 -137
- package/tools/demo-worker/api-client.mjs +0 -233
- package/tools/demo-worker/generate.mjs +0 -301
- package/tools/demo-worker/index.mjs +0 -466
- package/tools/demo-worker/sign-core.mjs +0 -112
- package/tools/demo-worker/sign.mjs +0 -161
- package/tools/gt-render/browser.mjs +0 -182
- package/tools/gt-render/camera-math.mjs +0 -276
- package/tools/gt-render/page.mjs +0 -267
- package/tools/gt-render/render.mjs +0 -514
- package/tools/gt-render/scene-box.mjs +0 -31
- package/tools/gt-render/take-transform.mjs +0 -87
- package/tools/kimodo/compare-seam.mjs +0 -108
- package/tools/kimodo/constraints.mjs +0 -244
- package/tools/kimodo/edit.mjs +0 -259
- package/tools/kimodo/effector-constraints.mjs +0 -200
- package/tools/kimodo/generate.mjs +0 -646
- package/tools/kimodo/local-output.mjs +0 -265
- package/tools/kimodo/measure-pose.mjs +0 -65
- package/tools/kimodo/measure-preserve.mjs +0 -899
- package/tools/kimodo/measure-waypoints.mjs +0 -55
- package/tools/kimodo/mlx-generate.py +0 -111
- package/tools/kimodo/pose-constraints.mjs +0 -248
- package/tools/kimodo/preserve-mask.mjs +0 -543
- package/tools/kimodo/read-npz.mjs +0 -189
- package/tools/kimodo/run-edit-on-box.mjs +0 -155
- package/tools/kimodo/run-sequence-on-box.mjs +0 -178
- package/tools/kimodo/runner.mjs +0 -284
- package/tools/kimodo/seam-batch.mjs +0 -77
- package/tools/kimodo/setup-local.mjs +0 -30
- package/tools/kimodo/setup-on-box.sh +0 -339
- package/tools/kimodo/soma77-to-cskel27.mjs +0 -305
- package/tools/morphgs/assets/gen_truth.py +0 -39
- package/tools/morphgs/assets/mesh_ori_rig.txt +0 -27
- package/tools/morphgs/assets/playback-check.mjs +0 -30
- package/tools/morphgs/demo-gate.sh +0 -26
- package/tools/morphgs/fbx2morphgs.mjs +0 -68
- package/tools/morphgs/morphgs-to-cskel27.mjs +0 -105
- package/tools/morphgs/patches/preprocess_src-none-mode.patch +0 -76
- package/tools/morphgs/setup-on-cluster.sh +0 -126
- package/tools/projflow/driver.py +0 -1069
- package/tools/projflow/generate.mjs +0 -805
- package/tools/projflow/hml22-to-cskel27.mjs +0 -735
- package/tools/projflow/line-edit-job.mjs +0 -547
- package/tools/projflow/replay.mjs +0 -452
- package/tools/projflow/runner.mjs +0 -269
- package/tools/projflow/service.mjs +0 -742
- package/tools/track/DESIGN.md +0 -513
- package/tools/track/backfill-provenance.mjs +0 -116
- package/tools/track/budget.mjs +0 -8
- package/tools/track/check-rig.mjs +0 -209
- package/tools/track/diagnostics.schema.json +0 -60
- package/tools/track/export-rig.mjs +0 -256
- package/tools/track/fallback.mjs +0 -7
- package/tools/track/fk-parity-fixture.mjs +0 -161
- package/tools/track/gate.mjs +0 -349
- package/tools/track/masks.mjs +0 -318
- package/tools/track/metrics.mjs +0 -201
- package/tools/track/publish-obs.mjs +0 -108
- package/tools/track/py/check_env.py +0 -61
- package/tools/track/py/eval_lr.py +0 -229
- package/tools/track/py/lr_viterbi.py +0 -294
- package/tools/track/py/masks.py +0 -405
- package/tools/track/py/objective.py +0 -382
- package/tools/track/py/rig.py +0 -508
- package/tools/track/py/scene.py +0 -326
- package/tools/track/py/test_joint_indices.py +0 -123
- package/tools/track/py/test_lr_viterbi.py +0 -195
- package/tools/track/py/test_masks.py +0 -229
- package/tools/track/py/test_rig.py +0 -288
- package/tools/track/py/test_scene.py +0 -354
- package/tools/track/py/test_track.py +0 -328
- package/tools/track/py/track.py +0 -411
- package/tools/track/remote.mjs +0 -140
- package/tools/track/rig-dump.mjs +0 -227
- package/tools/track/run-box-tests.mjs +0 -14
- package/tools/track/run-box.mjs +0 -168
- package/tools/track/setup-box.sh +0 -59
- package/tools/track/study-2d.mjs +0 -728
- /package/src/{ardy → motion}/collision-blockers.js +0 -0
- /package/src/{ardy → motion}/ground.js +0 -0
- /package/src/{ardy → motion}/ik-drag.js +0 -0
- /package/src/{ardy → motion}/ik-key-json.js +0 -0
- /package/src/{ardy → motion}/ik.js +0 -0
- /package/src/{ardy → motion}/physics-surface.js +0 -0
- /package/src/{ardy → motion}/playback-clock.js +0 -0
- /package/src/{ardy → motion}/range-pin.js +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Dump a Mixamo FBX rig's bind skeleton plus measured face/body landmarks to
|
|
2
|
+
// src/motion3/rigs/<model>.json for the motion3 compiler.
|
|
3
|
+
// Run once per rig: node tools/motion3/extract-rig.mjs x-bot-tpose
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import * as THREE from "three";
|
|
7
|
+
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
|
|
8
|
+
|
|
9
|
+
const model = process.argv[2] ?? "x-bot-tpose";
|
|
10
|
+
const buf = fs.readFileSync(path.resolve("public/models", `${model}.fbx`));
|
|
11
|
+
const root = new FBXLoader().parse(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength), "");
|
|
12
|
+
root.updateMatrixWorld(true);
|
|
13
|
+
let mesh = null;
|
|
14
|
+
root.traverse(o => { if (o.isSkinnedMesh && (!mesh || o.skeleton.bones.length > mesh.skeleton.bones.length)) mesh = o; });
|
|
15
|
+
// The whole bone hierarchy under the skinned Hips, end bones included (some rigs do not skin them).
|
|
16
|
+
const bones = [];
|
|
17
|
+
// Mixamo FBX nests an identity "skinned" copy of every bone under its control bone; the
|
|
18
|
+
// project rule (src/ardy/playback.js findBone) is first depth-first match wins, so keep
|
|
19
|
+
// the first bone of each name and never the nested copies.
|
|
20
|
+
const seen = new Set();
|
|
21
|
+
let top0 = mesh.skeleton.bones[0];
|
|
22
|
+
while (top0.parent?.isBone) top0 = top0.parent; // skinned bones may be the nested copies
|
|
23
|
+
top0.traverse(o => { if (o.isBone && !seen.has(o.name)) { seen.add(o.name); bones.push(o); } });
|
|
24
|
+
const idx = new Map(bones.map((b, i) => [b, i]));
|
|
25
|
+
const name = b => b.name.replace(/^mixamorig:?/, "");
|
|
26
|
+
const v = new THREE.Vector3(), q = new THREE.Quaternion(), s = new THREE.Vector3();
|
|
27
|
+
const out = { model, units: "cm", mesh: mesh.name, bones: bones.map(b => {
|
|
28
|
+
b.matrixWorld.decompose(v, q, s);
|
|
29
|
+
return { name: name(b), parent: idx.has(b.parent) ? idx.get(b.parent) : -1, localPos: b.position.toArray(), localQuat: b.quaternion.toArray(),
|
|
30
|
+
worldPos: v.toArray(), worldQuat: q.toArray() };
|
|
31
|
+
}) };
|
|
32
|
+
// Bind-pose vertices in world space (skinning at bind pose is the identity).
|
|
33
|
+
const pos = mesh.geometry.attributes.position, P = [];
|
|
34
|
+
for (let i = 0; i < pos.count; i++) P.push(v.fromBufferAttribute(pos, i).applyMatrix4(mesh.matrixWorld).toArray());
|
|
35
|
+
const B = n => out.bones.find(b => b.name === n).worldPos;
|
|
36
|
+
const head = B("Head"), neck = B("Neck");
|
|
37
|
+
// HeadTop_End is not in every rig (Y Bot has none): fall back to the highest skin vertex.
|
|
38
|
+
const top = out.bones.find(b => b.name === "HeadTop_End")?.worldPos
|
|
39
|
+
?? [head[0], Math.max(...P.filter(p => p[1] > head[1]).map(p => p[1])), head[2]];
|
|
40
|
+
// Head profile on the mid-sagittal strip |x| < 1.5 cm: the face is the front (+z) silhouette.
|
|
41
|
+
const strip = P.filter(p => Math.abs(p[0]) < 1.5 && p[1] > neck[1] && p[1] < top[1] + 2);
|
|
42
|
+
const rows = [];
|
|
43
|
+
for (let y = Math.floor(neck[1]); y < top[1]; y += 1) {
|
|
44
|
+
const r = strip.filter(p => p[1] >= y && p[1] < y + 1);
|
|
45
|
+
if (r.length) rows.push({ y: y + 0.5, front: Math.max(...r.map(p => p[2])), back: Math.min(...r.map(p => p[2])) });
|
|
46
|
+
}
|
|
47
|
+
// Head skin only: from 6 cm below the head joint up, inside |x| < 12 cm (keeps the shoulders out).
|
|
48
|
+
const headVerts = P.filter(p => p[1] > head[1] - 6 && Math.abs(p[0]) < 12);
|
|
49
|
+
const ext = k => [Math.min(...headVerts.map(p => p[k])), Math.max(...headVerts.map(p => p[k]))];
|
|
50
|
+
const hb = { x: ext(0), y: ext(1), z: ext(2) };
|
|
51
|
+
// The bot head has no modelled mouth: put it 16% of the head height above the chin, on
|
|
52
|
+
// the front silhouette (interpolated from the profile rows), 0.3 cm proud of the skin.
|
|
53
|
+
const mouthY = hb.y[0] + 0.16 * (hb.y[1] - hb.y[0]);
|
|
54
|
+
const near = rows.filter(r => r.front > 0).sort((a, b) => Math.abs(a.y - mouthY) - Math.abs(b.y - mouthY)).slice(0, 3);
|
|
55
|
+
const mouthZ = Math.max(...near.map(r => r.front)) + 0.3;
|
|
56
|
+
// The left foot's skin (every skinned mesh, vertices at least half weighted to LeftFoot/LeftToe*,
|
|
57
|
+
// the membership the verify_result floor measure uses). QA's ball and tip sole points ride the
|
|
58
|
+
// ToeBase and Toe_End joints this far down (cm, to the mm; < 0: the skin is above the joint):
|
|
59
|
+
// ball = the lowest skin under the toe pad (from ToeBase halfway to Toe_End), tip = the lowest
|
|
60
|
+
// skin in the front 1.5 cm of the foot.
|
|
61
|
+
const footSkin = [];
|
|
62
|
+
root.traverse(m => {
|
|
63
|
+
const g = m.isSkinnedMesh && m.geometry.attributes, wp = new THREE.Vector3();
|
|
64
|
+
if (!g?.skinIndex) return;
|
|
65
|
+
for (let i = 0; i < g.position.count; i++) {
|
|
66
|
+
let w = 0;
|
|
67
|
+
for (let j = 0; j < 4; j++) if (/LeftFoot|LeftToe/.test(m.skeleton.bones[g.skinIndex.getComponent(i, j)]?.name ?? "")) w += g.skinWeight.getComponent(i, j);
|
|
68
|
+
if (w >= 0.5) footSkin.push(wp.fromBufferAttribute(g.position, i).applyMatrix4(m.matrixWorld).toArray());
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
const toe = B("LeftToeBase"), toeEnd = B("LeftToe_End"), front = Math.max(...footSkin.map(p => p[2]));
|
|
72
|
+
const lowest = (z0, z1) => Math.min(...footSkin.filter(p => p[2] >= z0 && p[2] <= z1).map(p => p[1]));
|
|
73
|
+
const mm = x => Math.round(x * 10) / 10 || 0;
|
|
74
|
+
out.landmarks = {
|
|
75
|
+
// all in bind-pose world cm; the compiler re-expresses them in the Head bone frame
|
|
76
|
+
mouth: [0, mouthY, mouthZ],
|
|
77
|
+
headEllipsoid: { centre: [(hb.x[0] + hb.x[1]) / 2, (hb.y[0] + hb.y[1]) / 2, (hb.z[0] + hb.z[1]) / 2],
|
|
78
|
+
radii: [(hb.x[1] - hb.x[0]) / 2, (hb.y[1] - hb.y[0]) / 2, (hb.z[1] - hb.z[0]) / 2] },
|
|
79
|
+
headJoint: head, headTop: top,
|
|
80
|
+
sole: { ball: mm(toe[1] - lowest(toe[2], (toe[2] + toeEnd[2]) / 2)), tip: mm(toeEnd[1] - lowest(front - 1.5, front)) },
|
|
81
|
+
};
|
|
82
|
+
const file = path.resolve("src/motion3/rigs", `${model}.json`);
|
|
83
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
84
|
+
fs.writeFileSync(file, JSON.stringify(out));
|
|
85
|
+
console.log(JSON.stringify({ file, bones: out.bones.length, verts: P.length, landmarks: out.landmarks }));
|
|
@@ -27,94 +27,6 @@ export function waitForExit(child) {
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
function bridgeError(name, port, detail, code) {
|
|
31
|
-
const error = new Error(`${name} on 127.0.0.1:${port} ${detail}`);
|
|
32
|
-
error.code = code;
|
|
33
|
-
return error;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function waitForBridgeReady(child, { name, port, readyType, listenErrorType }, timeoutMs = 5000) {
|
|
37
|
-
return new Promise((resolve, reject) => {
|
|
38
|
-
let settled = false;
|
|
39
|
-
const finish = (callback, value) => {
|
|
40
|
-
if (settled) return;
|
|
41
|
-
settled = true;
|
|
42
|
-
clearTimeout(timeout);
|
|
43
|
-
child.off("message", onMessage);
|
|
44
|
-
child.off("exit", onExit);
|
|
45
|
-
child.off("error", onError);
|
|
46
|
-
callback(value);
|
|
47
|
-
};
|
|
48
|
-
const fail = (detail, code) => finish(reject, bridgeError(name, port, detail, code));
|
|
49
|
-
const onMessage = (message) => {
|
|
50
|
-
if (!message || message.port !== port) return;
|
|
51
|
-
if (message.type === readyType) finish(resolve);
|
|
52
|
-
if (message.type === listenErrorType) {
|
|
53
|
-
fail(`could not listen: ${message.code ?? "unknown error"}`, message.code);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
const onExit = (code, signal) => fail(`exited ${signal ? `from ${signal}` : `with code ${code ?? 0}`}`);
|
|
57
|
-
const onError = (error) => fail(`could not start: ${error.message}`);
|
|
58
|
-
const timeout = setTimeout(() => fail(`did not report readiness within ${timeoutMs} ms`), timeoutMs);
|
|
59
|
-
child.on("message", onMessage);
|
|
60
|
-
child.once("exit", onExit);
|
|
61
|
-
child.once("error", onError);
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export async function startBridge({
|
|
66
|
-
command,
|
|
67
|
-
args,
|
|
68
|
-
cwd,
|
|
69
|
-
env,
|
|
70
|
-
mainPort,
|
|
71
|
-
portEnv = "COZYCLAY_BRIDGE_PORT",
|
|
72
|
-
name = "motion bridge",
|
|
73
|
-
readyType = "cozyclay-bridge-ready",
|
|
74
|
-
listenErrorType = "cozyclay-bridge-listen-error",
|
|
75
|
-
onSpawn,
|
|
76
|
-
onFailure,
|
|
77
|
-
onReady,
|
|
78
|
-
}) {
|
|
79
|
-
const explicitPort = env[portEnv];
|
|
80
|
-
if (explicitPort !== undefined) {
|
|
81
|
-
const port = Number(explicitPort);
|
|
82
|
-
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
83
|
-
throw new Error(`${portEnv}=${JSON.stringify(explicitPort)} is not a valid port`);
|
|
84
|
-
}
|
|
85
|
-
return startBridgeAt(port, true);
|
|
86
|
-
}
|
|
87
|
-
for (let port = mainPort + 1; port <= 65535; port += 1) {
|
|
88
|
-
try {
|
|
89
|
-
return await startBridgeAt(port, false);
|
|
90
|
-
} catch (error) {
|
|
91
|
-
if (error?.code !== "EADDRINUSE") throw error;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
throw new Error(`no free bridge port is available at or above ${mainPort + 1}`);
|
|
95
|
-
|
|
96
|
-
async function startBridgeAt(port, isExplicit) {
|
|
97
|
-
const child = spawnOwned(command, args, {
|
|
98
|
-
cwd,
|
|
99
|
-
env: { ...env, [portEnv]: String(port) },
|
|
100
|
-
stdio: ["inherit", "inherit", "inherit", "ipc"],
|
|
101
|
-
});
|
|
102
|
-
onSpawn?.(child);
|
|
103
|
-
try {
|
|
104
|
-
await waitForBridgeReady(child, { name, port, readyType, listenErrorType });
|
|
105
|
-
onReady?.(child);
|
|
106
|
-
return { child, port };
|
|
107
|
-
} catch (error) {
|
|
108
|
-
onFailure?.(child);
|
|
109
|
-
await terminateOwned(child);
|
|
110
|
-
if (isExplicit && error?.code === "EADDRINUSE") {
|
|
111
|
-
throw new Error(`${portEnv}=${port} is already in use; choose another ${portEnv}`);
|
|
112
|
-
}
|
|
113
|
-
throw error;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
30
|
function signalOwned(child, signal) {
|
|
119
31
|
if (!child || child.exitCode !== null || child.signalCode !== null) return;
|
|
120
32
|
try {
|
package/tools/run-tests.mjs
CHANGED
|
@@ -14,84 +14,25 @@ if (!process.env.COZYCLAY_AGENT_SESSIONS_DIR) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const NODE_FILES = [
|
|
17
|
-
"test/verify-proxy-figure.mjs",
|
|
17
|
+
"test/motion3/verify-motion3-core.mjs", "test/motion3/verify-motion3-idle.mjs", "test/motion3/verify-motion3-timing.mjs", "test/motion3/verify-motion3-self.mjs", "test/motion3/verify-motion3-commands.mjs", "test/motion3/verify-motion3-exitcar.mjs", "test/motion3/verify-motion3-agentloop.mjs", "test/motion3/verify-motion3-search.mjs", "test/motion3/verify-motion3-skills.mjs", "test/motion3/verify-motion3-carried.mjs", "test/motion3/verify-motion3-contracts.mjs", "test/motion3/verify-motion3-describe.mjs", "test/motion3/verify-motion3-timeline.mjs", "test/motion3/verify-motion3-probes.mjs", "test/motion3/verify-motion3-grab.mjs", "test/motion3/verify-motion3-patch.mjs", "test/motion3/verify-motion3-repair.mjs", "test/motion3/verify-motion3-specstore.mjs", "test/motion3/verify-motion3-visual.mjs", "test/motion3/verify-motion3-goals.mjs", "test/motion3/verify-motion3-prompt.mjs", "test/motion3/verify-motion3-cup.mjs", "test/verify-proxy-figure.mjs",
|
|
18
18
|
"test/verify-proxy-figure-bounds.mjs",
|
|
19
19
|
"test/verify-character-capabilities.mjs",
|
|
20
20
|
"test/verify-root-path.mjs",
|
|
21
|
-
"test/verify-morphgs-exporter.mjs",
|
|
22
21
|
"test/verify-studio-elements.mjs",
|
|
23
22
|
"test/bus/verify-view-mode-pose.mjs",
|
|
24
23
|
"test/verify-studio-actions.mjs",
|
|
25
|
-
"test/ardy/verify-base-free.mjs",
|
|
26
|
-
"test/ardy/verify-browser-motion.mjs",
|
|
27
24
|
"test/ardy/verify-collision-blockers.mjs",
|
|
28
|
-
"test/ardy/verify-compare-npz.mjs",
|
|
29
|
-
"test/ardy/verify-fill.mjs",
|
|
30
|
-
"test/ardy/verify-fk.mjs",
|
|
31
|
-
"test/ardy/verify-gvhmr-worker.mjs",
|
|
32
|
-
"test/ardy/verify-mocap-quality-gate.mjs",
|
|
33
|
-
"test/ardy/verify-motion-calibration.mjs",
|
|
34
|
-
"test/ardy/verify-palette-segmentation.mjs",
|
|
35
|
-
"test/verify-motion-stabilize.mjs",
|
|
36
|
-
"test/verify-i2v-motion-prompt.mjs",
|
|
37
25
|
"test/verify-facing-marks.mjs",
|
|
38
26
|
"test/verify-pose-fade.mjs",
|
|
39
27
|
"test/verify-pose-gizmo.mjs",
|
|
40
|
-
"test/ardy/verify-gvhmr-floor.mjs",
|
|
41
|
-
"test/verify-gvhmr-detector-flag.mjs",
|
|
42
|
-
"test/verify-gvhmr-only.mjs",
|
|
43
|
-
"test/verify-extract-bench.mjs",
|
|
44
|
-
"test/verify-fit-bench.mjs",
|
|
45
|
-
"test/verify-obs-extrinsics.mjs",
|
|
46
|
-
"test/verify-obs-depth.mjs",
|
|
47
|
-
"test/verify-obs-ground.mjs",
|
|
48
|
-
"test/verify-obs-betas.mjs",
|
|
49
|
-
"test/verify-obs-remote.mjs",
|
|
50
|
-
"test/verify-track-run-box.mjs",
|
|
51
|
-
"test/verify-track-gate.mjs",
|
|
52
|
-
"test/verify-track-backfill.mjs",
|
|
53
|
-
"test/verify-track-remote.mjs",
|
|
54
|
-
"test/verify-track-metrics.mjs",
|
|
55
|
-
"test/verify-track-study-2d.mjs",
|
|
56
|
-
"test/verify-track-masks.mjs",
|
|
57
|
-
"test/verify-obs-ladder.mjs",
|
|
58
|
-
"test/verify-obs-isolation.mjs",
|
|
59
|
-
"test/verify-obs-bench-t1.mjs",
|
|
60
|
-
"test/verify-track-rig-dump.mjs",
|
|
61
|
-
"test/verify-scene-continuity.mjs",
|
|
62
|
-
"test/verify-heading-unwrap.mjs",
|
|
63
|
-
"test/verify-scene-ray.mjs",
|
|
64
|
-
"test/verify-footlock.mjs",
|
|
65
|
-
"test/verify-cube-contact.mjs",
|
|
66
28
|
"test/ardy/verify-key-runs.mjs",
|
|
67
|
-
"test/ardy/verify-playback-skinning.mjs",
|
|
68
29
|
"test/ardy/verify-playback-clock.mjs",
|
|
69
|
-
"test/ardy/verify-pose-export.mjs",
|
|
70
|
-
"test/ardy/verify-pose-pin.mjs",
|
|
71
|
-
"test/ardy/verify-pose-shape.mjs",
|
|
72
|
-
"test/ardy/verify-prompt-move.mjs",
|
|
73
|
-
"test/ardy/verify-rest.mjs",
|
|
74
|
-
"test/ardy/verify-root-drop.mjs",
|
|
75
|
-
"test/ardy/verify-surface-rise.mjs",
|
|
76
|
-
"test/ardy/verify-secure-artifacts.mjs",
|
|
77
|
-
"test/ardy/verify-motion-cors.mjs",
|
|
78
30
|
"test/ardy/verify-timeline-coordinates.mjs",
|
|
79
|
-
"test/ardy/verify-timeline-resize.mjs",
|
|
80
31
|
"test/verify-tokens.mjs",
|
|
81
|
-
"test/demo/verify-
|
|
82
|
-
"test/
|
|
83
|
-
"test/demo/verify-motion-url-allowlist.mjs",
|
|
84
|
-
"test/demo/verify-queue-policy.mjs",
|
|
85
|
-
"test/demo/verify-queue-concurrency.mjs",
|
|
86
|
-
"test/demo/verify-ops.mjs",
|
|
87
|
-
"test/demo/verify-demo-worker-signing.mjs",
|
|
88
|
-
"test/demo/verify-demo-worker-loop.mjs",
|
|
89
|
-
"test/ik/verify-fix-collisions.mjs",
|
|
90
|
-
"test/ik/verify-foot-lock.mjs",
|
|
32
|
+
"test/demo/verify-api-routes.mjs",
|
|
33
|
+
"test/ik/verify-collision-capsules.mjs",
|
|
91
34
|
"test/ik/verify-ground.mjs",
|
|
92
|
-
"test/ik/verify-auto-physics.mjs",
|
|
93
35
|
"test/ik/verify-physics-review.mjs",
|
|
94
|
-
"test/ik/verify-platform-fit.mjs",
|
|
95
36
|
"test/ik/verify-physics-support.mjs",
|
|
96
37
|
"test/ik/verify-physics-surface.mjs",
|
|
97
38
|
"test/ik/verify-ik.mjs",
|
|
@@ -104,13 +45,12 @@ const NODE_FILES = [
|
|
|
104
45
|
"test/ik/verify-range-pin-object-transform.mjs",
|
|
105
46
|
"test/verify-ik-camera-performance.mjs",
|
|
106
47
|
"test/verify-ik-entry-camera.mjs",
|
|
107
|
-
"test/process/verify-bridge-launch.mjs",
|
|
108
48
|
"test/process/verify-lifecycle.mjs",
|
|
109
49
|
"test/process/verify-mcp-package-isolation.mjs",
|
|
110
50
|
"test/process/verify-package-telemetry.mjs",
|
|
111
51
|
"test/process/verify-agent-deps.mjs",
|
|
112
52
|
"test/verify-agent-image-references.mjs",
|
|
113
|
-
"test/verify-agent-panel.mjs",
|
|
53
|
+
"test/verify-agent-panel.mjs", "test/verify-agent-turn-view.mjs", "test/verify-agent-reply-text.mjs",
|
|
114
54
|
"test/verify-agent-host.mjs",
|
|
115
55
|
"test/verify-agent-routes.mjs",
|
|
116
56
|
"test/verify-studio-owner-restart.mjs",
|
|
@@ -120,7 +60,7 @@ const NODE_FILES = [
|
|
|
120
60
|
"test/verify-agent-runner-errors.mjs",
|
|
121
61
|
"test/verify-agent-steer.mjs",
|
|
122
62
|
"test/verify-pi-tools.mjs",
|
|
123
|
-
"test/verify-agent-providers.mjs",
|
|
63
|
+
"test/verify-agent-providers.mjs", "test/verify-agent-login.mjs",
|
|
124
64
|
"test/verify-cliproxy-live-model.mjs",
|
|
125
65
|
"test/verify-schema-to-typebox.mjs",
|
|
126
66
|
"test/verify-agent-sse-golden.mjs",
|
|
@@ -129,7 +69,6 @@ const NODE_FILES = [
|
|
|
129
69
|
"test/verify-studio-agent-protocol.mjs",
|
|
130
70
|
"test/verify-studio-agent-sampled-framing.mjs",
|
|
131
71
|
"test/verify-studio-agent-tokens.mjs",
|
|
132
|
-
"test/verify-studio-agent-jobs.mjs",
|
|
133
72
|
"test/verify-agent-execution.mjs",
|
|
134
73
|
"test/verify-workflow-execution.mjs",
|
|
135
74
|
"test/verify-execution-shared-hooks.mjs",
|
|
@@ -157,8 +96,7 @@ const NODE_FILES = [
|
|
|
157
96
|
"test/verify-blocking-depth.mjs",
|
|
158
97
|
"test/verify-render-passes-video.mjs",
|
|
159
98
|
"test/verify-burn-in.mjs",
|
|
160
|
-
"test/verify-
|
|
161
|
-
"test/verify-camera-block.mjs",
|
|
99
|
+
"test/verify-camera-block.mjs", "test/verify-camera-direction.mjs",
|
|
162
100
|
"test/verify-camera-follow.mjs",
|
|
163
101
|
"test/verify-camera-move.mjs",
|
|
164
102
|
"test/verify-camera-rail-schedule.mjs",
|
|
@@ -169,78 +107,39 @@ const NODE_FILES = [
|
|
|
169
107
|
"test/verify-cuts.mjs",
|
|
170
108
|
"test/verify-shot-guides.mjs",
|
|
171
109
|
"test/verify-error-boundary.mjs",
|
|
172
|
-
"test/verify-footage-bridge.mjs",
|
|
173
110
|
"test/verify-g006-css.mjs",
|
|
174
111
|
"test/verify-gizmo-claim.mjs",
|
|
175
112
|
"test/verify-grid-view.mjs",
|
|
176
113
|
"test/verify-hierarchy.mjs",
|
|
177
114
|
"test/verify-history.mjs",
|
|
178
|
-
"test/verify-image-pose.mjs",
|
|
179
115
|
"test/verify-image-versions.mjs",
|
|
180
|
-
"test/verify-kimodo-cskel27.mjs",
|
|
181
|
-
"test/verify-kimodo-edit.mjs",
|
|
182
|
-
"test/verify-kimodo-effector.mjs",
|
|
183
|
-
"test/verify-kimodo-local-output.mjs", "test/verify-kimodo-mlx-output.mjs",
|
|
184
|
-
"test/verify-kimodo-pose.mjs",
|
|
185
|
-
"test/verify-kimodo-preserve.mjs",
|
|
186
|
-
"test/verify-kimodo-runner.mjs",
|
|
187
|
-
"test/verify-kimodo-setup.mjs",
|
|
188
|
-
"test/verify-motion-trail.mjs",
|
|
189
|
-
"test/verify-motion-trail-limb.mjs",
|
|
190
|
-
"test/verify-trail-key-conflicts.mjs",
|
|
191
|
-
"test/verify-motion-trail-orientation.mjs",
|
|
192
|
-
"test/verify-trail-pick.mjs",
|
|
193
|
-
"test/verify-trail-rendered-geometry.mjs",
|
|
194
|
-
"test/verify-motion-trail-overreach.mjs",
|
|
195
|
-
"test/verify-motion-trail-persistence.mjs",
|
|
196
|
-
"test/verify-kimodo-waypoints.mjs",
|
|
197
116
|
"test/verify-keyframe-pack.mjs",
|
|
198
117
|
"test/verify-keyframe-pack-request.mjs",
|
|
199
118
|
"test/verify-korean-ui.mjs",
|
|
200
119
|
"test/verify-label-tooltips.mjs",
|
|
201
120
|
"test/verify-layout.mjs",
|
|
202
121
|
"test/verify-beginner-screen.mjs",
|
|
203
|
-
"test/verify-line-edit-draw.mjs",
|
|
204
|
-
"test/verify-line-edit-pins.mjs",
|
|
205
122
|
"test/verify-live-agent-commands.mjs",
|
|
206
123
|
"test/verify-live-cli.mjs",
|
|
207
124
|
"test/verify-live-control.mjs",
|
|
208
125
|
"test/verify-matte-editor.mjs",
|
|
209
126
|
"test/verify-matte.mjs",
|
|
210
127
|
"test/verify-model-presets.mjs",
|
|
211
|
-
"test/verify-mp4-duration.mjs",
|
|
212
|
-
"test/verify-gt-render-camera.mjs",
|
|
213
|
-
"test/verify-bench-metrics.mjs",
|
|
214
128
|
"test/verify-mcp-invariants.mjs",
|
|
215
|
-
"test/verify-motion-edit.mjs",
|
|
216
|
-
"test/verify-motion-readiness.mjs",
|
|
217
|
-
"test/verify-demo-seed.mjs",
|
|
218
|
-
"test/verify-motion-readiness-ui.mjs",
|
|
219
|
-
"test/verify-multimodel-ingest.mjs",
|
|
220
129
|
"test/verify-offscreen-export.mjs",
|
|
221
130
|
"test/verify-export-capture.mjs",
|
|
222
131
|
"test/verify-export-recovery.mjs",
|
|
223
132
|
"test/verify-record-mp4-source.mjs",
|
|
224
133
|
"test/verify-timeline-extent.mjs",
|
|
225
134
|
"test/verify-otio.mjs",
|
|
226
|
-
"test/verify-pose-extract.mjs",
|
|
227
135
|
"test/verify-pose-library.mjs",
|
|
228
|
-
"test/verify-pose-mirror.mjs",
|
|
229
|
-
"test/verify-pose-yaw.mjs",
|
|
230
|
-
"test/verify-preserve-bridge.mjs",
|
|
231
136
|
"test/verify-project.mjs",
|
|
232
137
|
"test/verify-workflow-send.mjs",
|
|
233
138
|
"test/verify-animation-export.mjs",
|
|
234
139
|
"test/verify-project-previs-mode.mjs",
|
|
235
|
-
"test/verify-projflow-bridge.mjs",
|
|
236
|
-
"test/verify-projflow-cskel27.mjs",
|
|
237
|
-
"test/verify-projflow-replay.mjs",
|
|
238
|
-
"test/verify-projflow-runner.mjs",
|
|
239
|
-
"test/verify-projflow-service.mjs",
|
|
240
140
|
"test/verify-pwa.mjs",
|
|
241
141
|
"test/verify-package-signature.mjs",
|
|
242
142
|
"test/verify-resilience.mjs",
|
|
243
|
-
"test/verify-retime.mjs",
|
|
244
143
|
"test/verify-sample-at.mjs",
|
|
245
144
|
"test/verify-scene-asset-cache.mjs",
|
|
246
145
|
"test/verify-scene-assets.mjs",
|
|
@@ -277,7 +176,6 @@ const NODE_FILES = [
|
|
|
277
176
|
"test/verify-shot-meta.mjs",
|
|
278
177
|
"test/verify-shot-prompt.mjs",
|
|
279
178
|
"test/verify-shot-prompt-node.mjs",
|
|
280
|
-
"test/verify-take-recipe.mjs",
|
|
281
179
|
"test/verify-theme.mjs",
|
|
282
180
|
"test/verify-telemetry-state.mjs",
|
|
283
181
|
"test/verify-timeline-camera.mjs",
|
|
@@ -287,22 +185,18 @@ const NODE_FILES = [
|
|
|
287
185
|
"test/verify-shot-cast-overrides.mjs",
|
|
288
186
|
"test/verify-panel-stylize.mjs",
|
|
289
187
|
"test/verify-tool-handlers.mjs",
|
|
290
|
-
"test/verify-trim.mjs",
|
|
291
188
|
"test/verify-update-check.mjs",
|
|
292
189
|
"test/verify-usd-camera.mjs",
|
|
293
|
-
"test/verify-video-frames.mjs",
|
|
294
190
|
"test/verify-zip-store.mjs",
|
|
295
191
|
"test/verify-render-passes.mjs",
|
|
296
192
|
"mcp/verify.mjs",
|
|
297
193
|
"mcp/verify-http-origin.mjs",
|
|
298
194
|
"mcp/verify-live.mjs",
|
|
299
195
|
"mcp/verify-live-proxy-frame.mjs",
|
|
300
|
-
"mcp/verify-live-motion-job.mjs",
|
|
301
196
|
"mcp/verify-live-p0.mjs",
|
|
302
197
|
"mcp/verify-live-port.mjs",
|
|
303
198
|
"mcp/verify-live-controller.mjs",
|
|
304
199
|
"mcp/verify-live-routing.mjs",
|
|
305
|
-
"mcp/verify-prompts.mjs",
|
|
306
200
|
"mcp/verify-protocol-version.mjs",
|
|
307
201
|
"mcp/verify-tool-annotations.mjs",
|
|
308
202
|
"mcp/verify-import-mesh.mjs",
|
|
@@ -314,8 +208,6 @@ const NODE_FILES = [
|
|
|
314
208
|
"test/verify-group-rotation.mjs",
|
|
315
209
|
"test/verify-number-field-scrub.mjs",
|
|
316
210
|
"test/verify-speed-envelope.mjs",
|
|
317
|
-
"test/verify-motion-resources.mjs",
|
|
318
|
-
"test/verify-motion-store.mjs",
|
|
319
211
|
"test/verify-project-resources.mjs",
|
|
320
212
|
"test/verify-workflow-resources.mjs",
|
|
321
213
|
"test/verify-resource-status.mjs",
|
|
@@ -328,7 +220,6 @@ const BROWSER_FILES = [
|
|
|
328
220
|
"test/qa-storyboard-export-browser.mjs",
|
|
329
221
|
"test/qa-proxy-figure-browser.mjs",
|
|
330
222
|
"test/qa-rail-lean-browser.mjs",
|
|
331
|
-
"test/qa-motion-readiness-browser.mjs",
|
|
332
223
|
"test/qa-export-recovery-browser.mjs",
|
|
333
224
|
"test/verify-camera-mode-browser.mjs",
|
|
334
225
|
"test/verify-camera-rail-browser.mjs",
|
|
@@ -346,7 +237,6 @@ const BROWSER_FILES = [
|
|
|
346
237
|
"test/verify-settings-menu-browser.mjs",
|
|
347
238
|
"test/verify-static-shot-export-browser.mjs",
|
|
348
239
|
"test/qa-agent-view-toggle-browser.mjs",
|
|
349
|
-
"test/qa-studio-agent-browser.mjs",
|
|
350
240
|
"test/qa-agent-scenarios-browser.mjs",
|
|
351
241
|
"test/qa-camera-tutorial-browser.mjs",
|
|
352
242
|
"test/qa-first-shot-handoff-browser.mjs",
|
|
@@ -359,12 +249,9 @@ const BROWSER_FILES = [
|
|
|
359
249
|
"test/qa-reference-slots-browser.mjs",
|
|
360
250
|
"test/qa-scene-playback-browser.mjs",
|
|
361
251
|
"test/qa-scene-switcher-browser.mjs",
|
|
362
|
-
"test/qa-project-resources-browser.mjs",
|
|
363
252
|
"test/qa-send-to-ai-browser.mjs",
|
|
364
253
|
"test/qa-execution-outcomes-browser.mjs",
|
|
365
254
|
"test/qa-view-menu-browser.mjs",
|
|
366
|
-
"test/qa-agent-activity-browser.mjs",
|
|
367
|
-
"test/qa-platform-fit-browser.mjs",
|
|
368
255
|
"test/qa-scenes-v5-migration-browser.mjs",
|
|
369
256
|
"test/qa-clipboard-paste-browser.mjs",
|
|
370
257
|
"test/qa-rail-ring-browser.mjs",
|
|
@@ -375,7 +262,7 @@ const BROWSER_FILES = [
|
|
|
375
262
|
// The inventory sweep only picks up `verify*.mjs`; a browser suite named for
|
|
376
263
|
// the QA runner it needs is listed here so it still shows up in the manifest
|
|
377
264
|
// (as an EXCLUDE with its reason) instead of going unmentioned.
|
|
378
|
-
const EXTRA_INVENTORY = ["test/ik/translation-step.mjs", "test/qa-scenes-v5-migration-browser.mjs", "test/qa-
|
|
265
|
+
const EXTRA_INVENTORY = ["test/ik/translation-step.mjs", "test/qa-scenes-v5-migration-browser.mjs", "test/qa-agent-scenarios-browser.mjs", "test/qa-execution-outcomes-browser.mjs", "test/qa-export-recovery-browser.mjs", "test/qa-agent-view-toggle-browser.mjs", "test/qa-camera-tutorial-browser.mjs", "test/qa-first-shot-handoff-browser.mjs", "test/qa-tutorial-analytics-browser.mjs", "test/qa-camera-pointer-lock-browser.mjs", "test/qa-first-edit-browser.mjs", "test/qa-ia-tail-browser.mjs", "test/qa-keyframe-pack-browser.mjs", "test/qa-preview-browser.mjs", "test/qa-reference-slots-browser.mjs", "test/qa-scene-playback-browser.mjs", "test/qa-scene-switcher-browser.mjs", "test/qa-send-to-ai-browser.mjs", "test/qa-view-menu-browser.mjs", "test/qa-live-reconnect-browser.mjs", "test/qa-clipboard-paste-browser.mjs", "test/qa-rail-lean-browser.mjs", "test/qa-rail-reach-browser.mjs", "test/qa-rail-ring-browser.mjs", "test/qa-speed-graph-browser.mjs"];
|
|
379
266
|
|
|
380
267
|
EXTRA_INVENTORY.push("test/qa-proxy-figure-browser.mjs");
|
|
381
268
|
EXTRA_INVENTORY.push("test/qa-proxy-entry-browser.mjs");
|
|
@@ -466,10 +353,8 @@ function run(file, { buffered }) {
|
|
|
466
353
|
// instead of by luck. Everything else picks its port inside the process that
|
|
467
354
|
// keeps it.
|
|
468
355
|
const SERIAL_ONLY = new Set([
|
|
469
|
-
"test/process/verify-bridge-launch.mjs",
|
|
470
356
|
"mcp/verify-http-origin.mjs",
|
|
471
357
|
"mcp/verify-live-controller.mjs",
|
|
472
|
-
"mcp/verify-live-motion-job.mjs",
|
|
473
358
|
"mcp/verify-live-p0.mjs",
|
|
474
359
|
"mcp/verify-live-port.mjs",
|
|
475
360
|
"mcp/verify-live-routing.mjs",
|
|
@@ -479,7 +364,6 @@ const SERIAL_ONLY = new Set([
|
|
|
479
364
|
const SLOW_FIRST = [
|
|
480
365
|
"test/verify-studio-agent-motion.mjs",
|
|
481
366
|
"test/verify-studio-agent-binding.mjs",
|
|
482
|
-
"test/ardy/verify-gvhmr-floor.mjs",
|
|
483
367
|
"test/verify-part-colours.mjs",
|
|
484
368
|
"test/verify-agent-runner-errors.mjs",
|
|
485
369
|
];
|
|
@@ -508,7 +392,7 @@ async function runAll(files, jobs) {
|
|
|
508
392
|
// but older 22.x installs are still common enough that the manifest should
|
|
509
393
|
// degrade gracefully instead of aborting the whole run.
|
|
510
394
|
const NODE_SQLITE_MIN = [22, 13, 0];
|
|
511
|
-
const NODE_SQLITE_FILES = [
|
|
395
|
+
const NODE_SQLITE_FILES = [];
|
|
512
396
|
|
|
513
397
|
function meetsMinimumNodeVersion([major, minor, patch], current = process.versions.node) {
|
|
514
398
|
const [currentMajor, currentMinor, currentPatch] = current.split(".").map(Number);
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
// Stream decoding retained for the legacy MCP bridge client. Studio motion
|
|
2
|
-
// jobs run exclusively in the editor command bus; this module owns no jobs.
|
|
3
|
-
import { StudioProtocolError } from "../../src/studio-agent-protocol.js";
|
|
4
|
-
|
|
5
|
-
const motionUrlPattern = /^\/(ardy\/motions\/[0-9]+-[0-9a-f]{6}|ardy\/assembled\/[A-Za-z0-9._-]+\.npz)$/;
|
|
6
|
-
const error = (code, message) => new StudioProtocolError(code, message);
|
|
7
|
-
const MAX_RECORD_BYTES = 64 * 1024;
|
|
8
|
-
|
|
9
|
-
/** EOF is a record boundary, not a success signal. */
|
|
10
|
-
export function extractNdjsonRecords(buffer, { final = false } = {}) {
|
|
11
|
-
if (typeof buffer !== "string") throw new TypeError("NDJSON buffer must be a string");
|
|
12
|
-
const lines = buffer.split("\n");
|
|
13
|
-
const remainder = final ? "" : lines.pop();
|
|
14
|
-
const records = [];
|
|
15
|
-
for (const line of lines) {
|
|
16
|
-
if (Buffer.byteLength(line) > MAX_RECORD_BYTES) throw error("BACKEND_UNAVAILABLE", "Bridge record exceeds limit");
|
|
17
|
-
if (line.trim()) {
|
|
18
|
-
try { records.push(JSON.parse(line)); }
|
|
19
|
-
catch { throw error("BACKEND_UNAVAILABLE", final ? "Malformed final NDJSON record" : "Malformed NDJSON record"); }
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
if (Buffer.byteLength(remainder) > MAX_RECORD_BYTES) throw error("BACKEND_UNAVAILABLE", "Bridge record exceeds limit");
|
|
23
|
-
return { records, remainder };
|
|
24
|
-
}
|
|
25
|
-
async function refusalReason(response) {
|
|
26
|
-
if (!response.body) return null;
|
|
27
|
-
let body = "";
|
|
28
|
-
try {
|
|
29
|
-
const reader = response.body.getReader(); const decoder = new TextDecoder(); let bytes = 0;
|
|
30
|
-
try {
|
|
31
|
-
while (bytes < 64 * 1024) {
|
|
32
|
-
const chunk = await reader.read(); if (chunk.done) break;
|
|
33
|
-
const part = chunk.value.subarray(0, 64 * 1024 - bytes); bytes += part.byteLength; body += decoder.decode(part, { stream: bytes < 64 * 1024 });
|
|
34
|
-
if (part.byteLength < chunk.value.byteLength) break;
|
|
35
|
-
}
|
|
36
|
-
} finally { await reader.cancel().catch(() => {}); reader.releaseLock(); }
|
|
37
|
-
} catch { return null; }
|
|
38
|
-
try {
|
|
39
|
-
const value = JSON.parse(body);
|
|
40
|
-
for (const key of ["reason", "error", "message"]) if (typeof value?.[key] === "string" && value[key].trim()) return value[key].trim();
|
|
41
|
-
} catch {}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
export async function readMotionStream(response, { onProgress = () => {} } = {}) {
|
|
45
|
-
if (!response.ok || !response.body) {
|
|
46
|
-
const reason = response.ok ? null : await refusalReason(response);
|
|
47
|
-
if (response.status === 400) throw error("INVALID_ARGUMENT", `Bridge refused the request${reason ? `: ${reason}` : ""}`);
|
|
48
|
-
throw error("BACKEND_UNAVAILABLE", `Generation refused (HTTP ${response.status})${reason ? `: ${reason}` : ""}`);
|
|
49
|
-
}
|
|
50
|
-
const reader = response.body.getReader(); const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
51
|
-
let buffer = "", motionUrl = null, finished = false;
|
|
52
|
-
try {
|
|
53
|
-
for (;;) {
|
|
54
|
-
const chunk = await reader.read();
|
|
55
|
-
buffer += chunk.done ? decoder.decode() : decoder.decode(chunk.value, { stream: true });
|
|
56
|
-
const parsed = extractNdjsonRecords(buffer, { final: chunk.done }); buffer = parsed.remainder;
|
|
57
|
-
for (const record of parsed.records) {
|
|
58
|
-
if (!record || typeof record !== "object" || typeof record.event !== "string") throw error("BACKEND_UNAVAILABLE", "Invalid bridge record");
|
|
59
|
-
if (record.event === "error") {
|
|
60
|
-
const detail = [record.message, record.reason, record.error].find(value => typeof value === "string" && value.trim());
|
|
61
|
-
throw error("BACKEND_UNAVAILABLE", `Generator reported an error${detail ? `: ${detail.trim()}` : ""}`);
|
|
62
|
-
}
|
|
63
|
-
if (record.event === "done") {
|
|
64
|
-
if (typeof record.motionUrl !== "string" || !motionUrlPattern.test(record.motionUrl)) throw error("BACKEND_UNAVAILABLE", "Generator returned an invalid motion URL");
|
|
65
|
-
if (motionUrl && motionUrl !== record.motionUrl) throw error("BACKEND_UNAVAILABLE", "Conflicting final artifacts");
|
|
66
|
-
motionUrl = record.motionUrl;
|
|
67
|
-
} else if (Number.isFinite(record.progress)) onProgress(record.progress);
|
|
68
|
-
}
|
|
69
|
-
if (chunk.done) { finished = true; break; }
|
|
70
|
-
}
|
|
71
|
-
if (!motionUrl) throw error("BACKEND_UNAVAILABLE", "Generation ended without a motion");
|
|
72
|
-
return motionUrl;
|
|
73
|
-
} finally {
|
|
74
|
-
try { if (!finished) await reader.cancel(); } finally { reader.releaseLock(); }
|
|
75
|
-
}
|
|
76
|
-
}
|