@prestyj/cli 5.28.0 → 5.29.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/README.md +2 -2
- package/assets/motion/THIRD-PARTY.md +14 -19
- package/assets/motion/bin/contact-sheet.mjs +9 -3
- package/assets/motion/bin/cues.mjs +337 -0
- package/assets/motion/bin/flash-check.mjs +314 -0
- package/assets/motion/bin/fonts.mjs +17 -13
- package/assets/motion/bin/library.mjs +61 -18
- package/assets/motion/bin/motion-blur.mjs +943 -0
- package/assets/motion/bin/motion-check.mjs +366 -9
- package/assets/motion/bin/music-fit.mjs +436 -0
- package/assets/motion/bin/pdf-extract.mjs +22 -10
- package/assets/motion/bin/reference-study.mjs +346 -0
- package/assets/motion/bin/score-synth.mjs +1052 -93
- package/assets/motion/fonts/finger-paint/OFL.txt +93 -0
- package/assets/motion/fonts/finger-paint/finger-paint-normal.woff2 +0 -0
- package/assets/motion/fonts/fonts.json +56 -0
- package/assets/motion/fonts/short-stack/OFL.txt +94 -0
- package/assets/motion/fonts/short-stack/short-stack-normal.woff2 +0 -0
- package/assets/motion/fonts/sora/OFL.txt +93 -0
- package/assets/motion/fonts/sora/sora-normal.woff2 +0 -0
- package/assets/motion/fonts/specimen.jpg +0 -0
- package/assets/motion/fonts/unbounded/OFL.txt +93 -0
- package/assets/motion/fonts/unbounded/unbounded-normal.woff2 +0 -0
- package/assets/motion/library/README.md +52 -14
- package/assets/motion/library/kit/moves.js +1981 -0
- package/assets/motion/library/library.json +232 -0
- package/assets/motion/library/pieces/camera-rig/meta.json +13 -0
- package/assets/motion/library/pieces/camera-rig/piece.html +153 -0
- package/assets/motion/library/pieces/camera-rig/preview.jpg +0 -0
- package/assets/motion/library/pieces/chain-knock/meta.json +13 -0
- package/assets/motion/library/pieces/chain-knock/piece.html +195 -0
- package/assets/motion/library/pieces/chain-knock/preview.jpg +0 -0
- package/assets/motion/library/pieces/gather-to-logo/meta.json +13 -0
- package/assets/motion/library/pieces/gather-to-logo/piece.html +159 -0
- package/assets/motion/library/pieces/gather-to-logo/preview.jpg +0 -0
- package/assets/motion/library/pieces/morph-carry/meta.json +13 -0
- package/assets/motion/library/pieces/morph-carry/piece.html +173 -0
- package/assets/motion/library/pieces/morph-carry/preview.jpg +0 -0
- package/assets/motion/library/pieces/one-shape-journey/meta.json +13 -0
- package/assets/motion/library/pieces/one-shape-journey/piece.html +195 -0
- package/assets/motion/library/pieces/one-shape-journey/preview.jpg +0 -0
- package/assets/motion/library/pieces/open-from-subject/meta.json +13 -0
- package/assets/motion/library/pieces/open-from-subject/piece.html +168 -0
- package/assets/motion/library/pieces/open-from-subject/preview.jpg +0 -0
- package/assets/motion/library/pieces/request-to-result/meta.json +13 -0
- package/assets/motion/library/pieces/request-to-result/piece.html +212 -0
- package/assets/motion/library/pieces/request-to-result/preview.jpg +0 -0
- package/assets/motion/library/pieces/scale-dive/meta.json +13 -0
- package/assets/motion/library/pieces/scale-dive/piece.html +321 -0
- package/assets/motion/library/pieces/scale-dive/preview.jpg +0 -0
- package/assets/motion/library/pieces/screen-replica-steps/meta.json +13 -0
- package/assets/motion/library/pieces/screen-replica-steps/piece.html +366 -0
- package/assets/motion/library/pieces/screen-replica-steps/preview.jpg +0 -0
- package/assets/motion/library/pieces/zoom-into-card/meta.json +13 -0
- package/assets/motion/library/pieces/zoom-into-card/piece.html +179 -0
- package/assets/motion/library/pieces/zoom-into-card/preview.jpg +0 -0
- package/assets/motion/library/sheets/diagram.jpg +0 -0
- package/assets/motion/library/sheets/frame.jpg +0 -0
- package/assets/motion/library/sheets/transition.jpg +0 -0
- package/assets/motion/library/sheets/ui.jpg +0 -0
- package/assets/motion/plugin.json +1 -1
- package/assets/motion/references/build-sheet.md +206 -0
- package/assets/motion/references/runtime/determinism-rules.md +3 -3
- package/assets/motion/references/runtime/gsap-easing-and-stagger.md +28 -28
- package/assets/motion/references/runtime/gsap.md +3 -3
- package/assets/motion/references/runtime/inputs-and-assets.md +21 -16
- package/assets/motion/references/runtime/lint-validate-inspect.md +3 -3
- package/assets/motion/references/runtime/minimal-composition.md +6 -0
- package/assets/motion/references/runtime/preview-render.md +3 -3
- package/assets/motion/skills/app-walkthrough/SKILL.md +66 -0
- package/assets/motion/skills/before-after/SKILL.md +53 -0
- package/assets/motion/skills/brand-kit/SKILL.md +17 -16
- package/assets/motion/skills/dev-tool-video/SKILL.md +57 -0
- package/assets/motion/skills/launch-video/SKILL.md +62 -0
- package/assets/motion/skills/match-reference/SKILL.md +58 -0
- package/assets/motion/skills/motion/SKILL.md +167 -98
- package/assets/motion/skills/source-ingest/SKILL.md +23 -15
- package/assets/motion/skills/website-video/SKILL.md +59 -0
- package/assets/skills/bulletproof/SKILL.md +36 -11
- package/assets/skills/bulletproof/references/agent-surface.md +19 -9
- package/assets/skills/bulletproof/references/audit-protocol.md +20 -5
- package/assets/skills/bulletproof/references/platform-playbooks.md +5 -4
- package/assets/skills/bulletproof/references/provenance.md +26 -1
- package/assets/skills/bulletproof/references/secure-defaults.md +6 -5
- package/assets/skills/bulletproof/references/supply-chain.md +21 -17
- package/assets/skills/bulletproof/references/threat-landscape.md +28 -26
- package/assets/skills/bulletproof/references/verification.md +2 -0
- package/assets/skills/clarify/SKILL.md +25 -16
- package/assets/skills/code-review/SKILL.md +71 -13
- package/assets/skills/code-review/references/agent-diffs.md +27 -0
- package/assets/skills/code-review/references/tests.md +19 -0
- package/assets/skills/compliance-guard/SKILL.md +20 -5
- package/assets/skills/compliance-guard/references/artifacts.md +1 -1
- package/assets/skills/compliance-guard/references/eu-uk.md +16 -16
- package/assets/skills/compliance-guard/references/lawsuit-vectors.md +5 -5
- package/assets/skills/compliance-guard/references/provenance.md +41 -2
- package/assets/skills/compliance-guard/references/sector-gates.md +3 -3
- package/assets/skills/compliance-guard/references/security-baseline.md +2 -2
- package/assets/skills/compliance-guard/references/trigger-map.md +5 -5
- package/assets/skills/compliance-guard/references/us.md +27 -21
- package/assets/skills/durable/SKILL.md +87 -79
- package/assets/skills/durable/references/agent-db-safety.md +69 -0
- package/assets/skills/durable/references/backups-and-runtime.md +19 -12
- package/assets/skills/durable/references/migrations-and-schema.md +13 -6
- package/assets/skills/evidence-led-ui/SKILL.md +69 -127
- package/assets/skills/evidence-led-ui/references/anti-defaults.md +107 -208
- package/assets/skills/evidence-led-ui/references/direction.md +124 -0
- package/assets/skills/evidence-led-ui/references/production-contract.md +8 -0
- package/assets/skills/evidence-led-ui/references/provenance.md +24 -1
- package/assets/skills/lean/SKILL.md +90 -71
- package/assets/skills/lean/references/memory-and-processes.md +3 -2
- package/assets/skills/lean/references/playbooks.md +37 -12
- package/assets/skills/refactoring/SKILL.md +24 -3
- package/assets/skills/refactoring/references/agent-pitfalls.md +4 -1
- package/assets/skills/refactoring/references/legacy.md +21 -0
- package/assets/skills/root-cause/SKILL.md +20 -10
- package/assets/skills/shared-language/SKILL.md +16 -14
- package/assets/skills/tdd/SKILL.md +27 -15
- package/dist/app-sidecar.js +203 -47
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli.js +20 -28
- package/dist/cli.js.map +1 -1
- package/dist/core/acceptance-checks.d.ts +48 -0
- package/dist/core/acceptance-checks.js +144 -0
- package/dist/core/acceptance-checks.js.map +1 -0
- package/dist/core/agent-session.d.ts +119 -75
- package/dist/core/agent-session.js +561 -395
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agents.d.ts +6 -5
- package/dist/core/agents.js +12 -3
- package/dist/core/agents.js.map +1 -1
- package/dist/core/ask-user.d.ts +90 -8
- package/dist/core/ask-user.js +124 -13
- package/dist/core/ask-user.js.map +1 -1
- package/dist/core/auth-providers.js +1 -1
- package/dist/core/auth-providers.js.map +1 -1
- package/dist/core/autopilot-verdict.d.ts +5 -1
- package/dist/core/autopilot-verdict.js +30 -13
- package/dist/core/autopilot-verdict.js.map +1 -1
- package/dist/core/bundled-agents.js +1 -3
- package/dist/core/bundled-agents.js.map +1 -1
- package/dist/core/cache-diagnostics.d.ts +68 -0
- package/dist/core/cache-diagnostics.js +196 -0
- package/dist/core/cache-diagnostics.js.map +1 -0
- package/dist/core/cache-expiry.d.ts +87 -0
- package/dist/core/cache-expiry.js +111 -0
- package/dist/core/cache-expiry.js.map +1 -0
- package/dist/core/compaction/compactor.js +78 -48
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/compaction/plan-step-policy.d.ts +46 -0
- package/dist/core/compaction/plan-step-policy.js +57 -0
- package/dist/core/compaction/plan-step-policy.js.map +1 -0
- package/dist/core/destructive-git-guard.d.ts +90 -0
- package/dist/core/destructive-git-guard.js +871 -0
- package/dist/core/destructive-git-guard.js.map +1 -0
- package/dist/core/event-bus.d.ts +3 -0
- package/dist/core/event-bus.js +5 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/fast-apply-benchmark.d.ts +1 -1
- package/dist/core/fast-apply-benchmark.js +2 -2
- package/dist/core/fast-apply-benchmark.js.map +1 -1
- package/dist/core/injection-detect.d.ts +38 -0
- package/dist/core/injection-detect.js +232 -0
- package/dist/core/injection-detect.js.map +1 -0
- package/dist/core/keep-awake.d.ts +88 -0
- package/dist/core/keep-awake.js +251 -0
- package/dist/core/keep-awake.js.map +1 -0
- package/dist/core/mcp/client.d.ts +72 -0
- package/dist/core/mcp/client.js +264 -41
- package/dist/core/mcp/client.js.map +1 -1
- package/dist/core/mcp/content.js +6 -2
- package/dist/core/mcp/content.js.map +1 -1
- package/dist/core/mcp/store.d.ts +6 -1
- package/dist/core/mcp/store.js +12 -1
- package/dist/core/mcp/store.js.map +1 -1
- package/dist/core/mcp/types.d.ts +18 -0
- package/dist/core/model-unavailable.d.ts +14 -0
- package/dist/core/model-unavailable.js +23 -0
- package/dist/core/model-unavailable.js.map +1 -0
- package/dist/core/node-debugger.d.ts +148 -0
- package/dist/core/node-debugger.js +642 -0
- package/dist/core/node-debugger.js.map +1 -0
- package/dist/core/nolan-context.d.ts +7 -5
- package/dist/core/nolan-context.js +106 -16
- package/dist/core/nolan-context.js.map +1 -1
- package/dist/core/nolan-prompt.js +24 -21
- package/dist/core/nolan-prompt.js.map +1 -1
- package/dist/core/package-threats.d.ts +18 -0
- package/dist/core/package-threats.js +168 -0
- package/dist/core/package-threats.js.map +1 -0
- package/dist/core/persistent-shell.d.ts +58 -6
- package/dist/core/persistent-shell.js +331 -49
- package/dist/core/persistent-shell.js.map +1 -1
- package/dist/core/process-manager.d.ts +14 -0
- package/dist/core/process-manager.js +61 -0
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/progress/git-xp.js +8 -14
- package/dist/core/progress/git-xp.js.map +1 -1
- package/dist/core/project-discovery.js +77 -26
- package/dist/core/project-discovery.js.map +1 -1
- package/dist/core/semantic-search-benchmark.d.ts +1 -1
- package/dist/core/semantic-search-benchmark.js +2 -2
- package/dist/core/semantic-search-benchmark.js.map +1 -1
- package/dist/core/session-history.d.ts +12 -0
- package/dist/core/session-history.js +27 -0
- package/dist/core/session-history.js.map +1 -1
- package/dist/core/session-manager.d.ts +13 -1
- package/dist/core/session-manager.js +38 -18
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-summary-index.d.ts +37 -0
- package/dist/core/session-summary-index.js +172 -0
- package/dist/core/session-summary-index.js.map +1 -0
- package/dist/core/settings-manager.d.ts +2 -0
- package/dist/core/settings-manager.js +10 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/shell-threats-popular-packages.d.ts +11 -0
- package/dist/core/shell-threats-popular-packages.js +675 -0
- package/dist/core/shell-threats-popular-packages.js.map +1 -0
- package/dist/core/shell-threats.d.ts +8 -0
- package/dist/core/shell-threats.js +186 -0
- package/dist/core/shell-threats.js.map +1 -0
- package/dist/core/skills.js +16 -4
- package/dist/core/skills.js.map +1 -1
- package/dist/core/stream-rules.d.ts +30 -0
- package/dist/core/stream-rules.js +151 -0
- package/dist/core/stream-rules.js.map +1 -0
- package/dist/core/subagent-manager.d.ts +23 -6
- package/dist/core/subagent-manager.js +25 -9
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-policy.js +1 -1
- package/dist/core/subagent-policy.js.map +1 -1
- package/dist/core/subagent-receipt.d.ts +54 -0
- package/dist/core/subagent-receipt.js +276 -0
- package/dist/core/subagent-receipt.js.map +1 -0
- package/dist/core/subagent-turn-record.d.ts +2 -0
- package/dist/core/subagent-turn-record.js.map +1 -1
- package/dist/core/test-impact.d.ts +73 -0
- package/dist/core/test-impact.js +467 -0
- package/dist/core/test-impact.js.map +1 -0
- package/dist/core/thinking-level.d.ts +1 -1
- package/dist/core/thinking-level.js +1 -1
- package/dist/core/thinking-level.js.map +1 -1
- package/dist/core/verification-gate.d.ts +2 -0
- package/dist/core/verification-gate.js +4 -0
- package/dist/core/verification-gate.js.map +1 -1
- package/dist/core/verification-snapshot.js +3 -5
- package/dist/core/verification-snapshot.js.map +1 -1
- package/dist/core/workspace-guard.d.ts +18 -7
- package/dist/core/workspace-guard.js +227 -60
- package/dist/core/workspace-guard.js.map +1 -1
- package/dist/core/worktree-setup.d.ts +23 -0
- package/dist/core/worktree-setup.js +128 -9
- package/dist/core/worktree-setup.js.map +1 -1
- package/dist/core/worktree.d.ts +20 -2
- package/dist/core/worktree.js +74 -31
- package/dist/core/worktree.js.map +1 -1
- package/dist/interactive.js +2 -1
- package/dist/interactive.js.map +1 -1
- package/dist/modes/json-mode.js +11 -2
- package/dist/modes/json-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +36 -1
- package/dist/modes/subagent-worker-mode.js +100 -42
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/motion-agent/motion-agent.d.ts +7 -3
- package/dist/motion-agent/motion-agent.js +6 -8
- package/dist/motion-agent/motion-agent.js.map +1 -1
- package/dist/motion-agent/motion-prompt.d.ts +1 -1
- package/dist/motion-agent/motion-prompt.js +16 -25
- package/dist/motion-agent/motion-prompt.js.map +1 -1
- package/dist/motion-agent/motion-review-session.js +1 -1
- package/dist/motion-agent/motion-review-session.js.map +1 -1
- package/dist/motion-agent/motion-review.d.ts +10 -3
- package/dist/motion-agent/motion-review.js +15 -7
- package/dist/motion-agent/motion-review.js.map +1 -1
- package/dist/motion-agent/motion-studio-context.js +1 -1
- package/dist/motion-agent/motion-studio-context.js.map +1 -1
- package/dist/system-prompt.d.ts +2 -1
- package/dist/system-prompt.js +15 -4
- package/dist/system-prompt.js.map +1 -1
- package/dist/test-support/keep-alive.d.ts +14 -0
- package/dist/test-support/keep-alive.js +17 -0
- package/dist/test-support/keep-alive.js.map +1 -0
- package/dist/tools/ask-user.js +3 -3
- package/dist/tools/ask-user.js.map +1 -1
- package/dist/tools/bash-read-evidence.d.ts +10 -0
- package/dist/tools/bash-read-evidence.js +133 -0
- package/dist/tools/bash-read-evidence.js.map +1 -0
- package/dist/tools/bash.d.ts +10 -1
- package/dist/tools/bash.js +179 -7
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/debug.d.ts +54 -0
- package/dist/tools/debug.js +233 -0
- package/dist/tools/debug.js.map +1 -0
- package/dist/tools/edit.js +13 -5
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/goals.d.ts +1 -1
- package/dist/tools/index.d.ts +25 -2
- package/dist/tools/index.js +48 -7
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/prompt-hints.js +2 -0
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/read-tracker.d.ts +35 -2
- package/dist/tools/read-tracker.js +108 -11
- package/dist/tools/read-tracker.js.map +1 -1
- package/dist/tools/read.js +39 -7
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/skill.js +5 -0
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/subagent-control.js +44 -8
- package/dist/tools/subagent-control.js.map +1 -1
- package/dist/tools/subagent-shared.d.ts +48 -8
- package/dist/tools/subagent-shared.js +75 -14
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/subagent.d.ts +8 -2
- package/dist/tools/subagent.js +28 -10
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/task-output.js +3 -2
- package/dist/tools/task-output.js.map +1 -1
- package/dist/tools/task-send.d.ts +1 -1
- package/dist/tools/task-send.js +15 -1
- package/dist/tools/task-send.js.map +1 -1
- package/dist/tools/tool-tiers.d.ts +2 -2
- package/dist/tools/tool-tiers.js +3 -2
- package/dist/tools/tool-tiers.js.map +1 -1
- package/dist/tools/truncate.d.ts +21 -0
- package/dist/tools/truncate.js +187 -0
- package/dist/tools/truncate.js.map +1 -1
- package/dist/tools/ui-adopt.js +2 -0
- package/dist/tools/ui-adopt.js.map +1 -1
- package/dist/tools/write.js +4 -3
- package/dist/tools/write.js.map +1 -1
- package/dist/ui/App.d.ts +0 -4
- package/dist/ui/App.js +5 -28
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/components/ActivityIndicator.js +1 -0
- package/dist/ui/components/ActivityIndicator.js.map +1 -1
- package/dist/ui/components/Footer.js +1 -1
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +1 -8
- package/dist/ui/hooks/useAgentLoop.js +1 -119
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/render.d.ts +2 -4
- package/dist/ui/render.js +3 -2
- package/dist/ui/render.js.map +1 -1
- package/dist/utils/git.d.ts +77 -0
- package/dist/utils/git.js +285 -21
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/github-ci.js +2 -1
- package/dist/utils/github-ci.js.map +1 -1
- package/dist/utils/github.js +11 -9
- package/dist/utils/github.js.map +1 -1
- package/dist/utils/image.d.ts +14 -0
- package/dist/utils/image.js +16 -0
- package/dist/utils/image.js.map +1 -1
- package/dist/utils/process.d.ts +20 -0
- package/dist/utils/process.js +98 -0
- package/dist/utils/process.js.map +1 -1
- package/dist/utils/text.d.ts +12 -0
- package/dist/utils/text.js +11 -0
- package/dist/utils/text.js.map +1 -1
- package/package.json +6 -6
- package/assets/motion/skills/mixkit-split-text-617/SKILL.md +0 -115
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-480.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-494.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-5.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-508.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6525.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6539.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6647.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6663.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6677.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6691.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6706.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6722.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6736.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6750.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6764.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6780.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6794.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6810.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6823.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6872.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6936.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-76.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/manifest.json +0 -495
- package/assets/motion/skills/mixkit-split-text-617/references/RECONSTRUCTION.md +0 -201
- package/assets/motion/skills/mixkit-split-text-617/references/VERIFICATION.md +0 -107
- package/assets/motion/skills/mixkit-split-text-617/tools/inspect_motion.py +0 -130
- package/assets/motion/skills/video-qa/SKILL.md +0 -66
- package/dist/core/ideal-review-subagent.d.ts +0 -42
- package/dist/core/ideal-review-subagent.js +0 -95
- package/dist/core/ideal-review-subagent.js.map +0 -1
- package/dist/core/ideal-review.d.ts +0 -82
- package/dist/core/ideal-review.js +0 -242
- package/dist/core/ideal-review.js.map +0 -1
- package/dist/motion-agent/motion-check-tool.d.ts +0 -21
- package/dist/motion-agent/motion-check-tool.js +0 -206
- package/dist/motion-agent/motion-check-tool.js.map +0 -1
package/README.md
CHANGED
|
@@ -71,7 +71,7 @@ Switch mid-conversation with `/model`. Not locked to anyone.
|
|
|
71
71
|
| Provider | Models | Auth |
|
|
72
72
|
| ----------------- | ---------------------------------------------------------------------------- | ---------------- |
|
|
73
73
|
| **Anthropic** | Claude Fable 5.1, Opus 5.5, Sonnet 5.5, Haiku 4.5 | OAuth |
|
|
74
|
-
| **OpenAI** | GPT-6 Astra, GPT-6 Sol, GPT-6 Luna
|
|
74
|
+
| **OpenAI** | GPT-6 Astra, GPT-6.1 Sol, GPT-6 Luna | OAuth |
|
|
75
75
|
| **Moonshot** | Kimi K3, Kimi K2.8 Preview, Kimi K2.7 Code | OAuth or API key |
|
|
76
76
|
| **Z.AI (GLM)** | GLM-5.3, GLM-5.3-Flash (image) | API key |
|
|
77
77
|
| **MiniMax** | MiniMax M3 (image + video) | API key |
|
|
@@ -177,7 +177,7 @@ Plus the [Grep MCP](https://grep.dev) for searching across 1M+ public GitHub rep
|
|
|
177
177
|
|
|
178
178
|
`subagent` remains blocking. The async suite launches persistent NDJSON worker processes, so a parent can start up to four active child turns, keep working, steer them, and wait for any or all results. Up to eight idle workers remain available for follow-up; bounded snapshots retain the latest 20 agents.
|
|
179
179
|
|
|
180
|
-
Only GPT-6 Astra
|
|
180
|
+
Only GPT-6 Astra and GPT-6.1 Sol at **Ultra** delegate proactively. Lower Astra/Sol levels use async agents only when the user or project/skill instructions request delegation; other models receive no proactive policy.
|
|
181
181
|
|
|
182
182
|
Children share the parent working directory by default, so parallel writes must target disjoint files or subsystems. Pass `isolate: true` to `subagent` to give a child its own copy of the repo on a new branch instead — the right choice when several children edit at once, or when a child's changes should land on a branch of their own. The copy is reclaimed automatically when the child finishes without committing; a child that did commit keeps its branch, because that branch is the deliverable. `/integrate` then merges those branches one at a time, running the suite between each. Async fan-out is one level deep, child output is bounded, idle workers reap after 10 minutes, and workers are not resumable after a CLI/app restart.
|
|
183
183
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Third-party content in EZ Motion
|
|
2
2
|
|
|
3
|
-
Motion exposes GG-authored
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
Motion exposes GG-authored skills and craft references. The old upstream
|
|
4
|
+
creative/workflow skills and guidance adapters have been removed. Retained
|
|
5
|
+
technical references are adapted for GG's pinned launcher and local-only safety
|
|
6
|
+
boundaries; do not restore entire upstream skill folders when updating the
|
|
7
|
+
runtime.
|
|
8
8
|
|
|
9
9
|
| Component | Source | Pinned at | License |
|
|
10
10
|
|---|---|---|---|
|
|
@@ -14,17 +14,11 @@ upstream skill folders when updating the runtime.
|
|
|
14
14
|
| Style-library pieces marked MIT (`library/pieces/<id>/`) | Magic UI, https://github.com/magicuidesign/magicui | converted 2026-09-28; upstream file URL in each `meta.json` | MIT (`LICENSE` beside each piece) |
|
|
15
15
|
| Fonts (`fonts/<family>/`) | Google Fonts / https://github.com/google/fonts | fetched 2026-09-28 by `scripts/fetch-motion-fonts.mjs` | SIL OFL 1.1 (`OFL.txt` beside each family) |
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## Content boundaries
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
source preview video or source font binary is bundled with that recipe.
|
|
23
|
-
|
|
24
|
-
Private extraction tools, source projects, working exports and authoring-method
|
|
25
|
-
documents are Git-ignored and excluded from release packaging. They are not
|
|
26
|
-
runtime dependencies or additional callable skills. The normal video agent uses
|
|
27
|
-
installed recipes; it does not run a parser or install authoring dependencies.
|
|
19
|
+
Motion ships no templates derived from third-party After Effects or other
|
|
20
|
+
motion projects. The earlier Mixkit, Mobile Notification and Kinetic Text
|
|
21
|
+
reconstructions were removed on 2026-09-29 and are not part of any release.
|
|
28
22
|
|
|
29
23
|
Existing `references/index.json`, signal sources and compact temporal JPEGs are
|
|
30
24
|
GG studies, not private user videos or a universal style. They remain optional
|
|
@@ -34,14 +28,15 @@ licenses remain with their sources.
|
|
|
34
28
|
|
|
35
29
|
The Motion-only preference reader and review tool do not load Coder instructions.
|
|
36
30
|
Review remains bounded and tied to current source/render evidence. It checks the
|
|
37
|
-
|
|
31
|
+
video's plan and approved inputs, not a competing art direction, and does not
|
|
38
32
|
claim full playback or aesthetic certification from model image critique.
|
|
39
33
|
|
|
40
34
|
## Fonts
|
|
41
35
|
|
|
42
|
-
|
|
43
|
-
by Google Fonts, except Mona Sans
|
|
44
|
-
Names and ship as complete upstream fonts, recompressed
|
|
36
|
+
19 families, listed in `fonts/fonts.json`. Latin-subset variable woff2 as served
|
|
37
|
+
by Google Fonts, except Mona Sans, Hubot Sans, Short Stack and Finger Paint: they
|
|
38
|
+
carry OFL Reserved Font Names and ship as complete upstream fonts, recompressed
|
|
39
|
+
to woff2. Unbounded, Sora, Short Stack and Finger Paint were added 2026-09-29. `fonts.mjs add`
|
|
45
40
|
copies each family's `OFL.txt` into the video project with its font files.
|
|
46
41
|
|
|
47
42
|
## Shared audio retained from brag
|
|
@@ -17,7 +17,9 @@ function fail(message) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const args = process.argv.slice(2);
|
|
20
|
-
const positional = args.filter(
|
|
20
|
+
const positional = args.filter(
|
|
21
|
+
(a, i) => !a.startsWith("--") && !args[i - 1]?.match(/^--(cols|width)$/),
|
|
22
|
+
);
|
|
21
23
|
const [framesArg, outArg] = positional;
|
|
22
24
|
if (!framesArg || !outArg) {
|
|
23
25
|
fail("usage: contact-sheet.mjs <frames-dir> <out.jpg> [--cols 4] [--width 1600] [--phone]");
|
|
@@ -39,13 +41,17 @@ try {
|
|
|
39
41
|
const hfPkg = require.resolve("hyperframes/package.json");
|
|
40
42
|
sharp = createRequire(hfPkg)("sharp");
|
|
41
43
|
} catch {
|
|
42
|
-
fail(
|
|
44
|
+
fail(
|
|
45
|
+
"Contact sheets need the HyperFrames bundled with EZ. Reinstall EZ Coder to restore Motion mode.",
|
|
46
|
+
);
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
const framesDir = resolve(framesArg);
|
|
46
50
|
const names = await readdir(framesDir).catch(() => fail(`Frames folder not found: ${framesDir}`));
|
|
47
51
|
// Skip sheets from earlier runs (snapshot writes contact-sheet.jpg beside its frames).
|
|
48
|
-
const entries = names.filter(
|
|
52
|
+
const entries = names.filter(
|
|
53
|
+
(n) => /\.(png|jpe?g|webp)$/i.test(n) && !/contact-sheet|phone-strip/i.test(n),
|
|
54
|
+
);
|
|
49
55
|
if (entries.length === 0) fail(`No frame images in ${framesDir}`);
|
|
50
56
|
const order = (name) => {
|
|
51
57
|
const m = basename(name, extname(name)).match(/(\d+(?:\.\d+)?)(?!.*\d)/);
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// EZ Motion cue export: load a composition the way a render does and write the
|
|
3
|
+
// sound cues its script marked with `kit.cue(tl, at, sfx)` to a JSON file that
|
|
4
|
+
// score-synth reads (`"cues": "cues.json"` in the score). Retime the animation,
|
|
5
|
+
// export again, and every sound moves with its event.
|
|
6
|
+
//
|
|
7
|
+
// Usage: node cues.mjs <project-dir> [--out <cues.json>] [--composition <file.html>]
|
|
8
|
+
// Default out: <project>/cues.json. Prints a one-line JSON summary.
|
|
9
|
+
//
|
|
10
|
+
// The page is served read-only from 127.0.0.1 to HyperFrames' own Chrome
|
|
11
|
+
// (`hf browser path`), driven over DevTools by HyperFrames' own puppeteer-core,
|
|
12
|
+
// which runs the script and returns the finished DOM. (Chrome's one-shot
|
|
13
|
+
// `--dump-dom` hangs in a full Chrome build on macOS, the fallback when the
|
|
14
|
+
// managed headless shell is missing.)
|
|
15
|
+
import { execFile } from "node:child_process";
|
|
16
|
+
import { createReadStream } from "node:fs";
|
|
17
|
+
import { mkdtemp, realpath, rm, stat, writeFile } from "node:fs/promises";
|
|
18
|
+
import { createServer } from "node:http";
|
|
19
|
+
import { createRequire } from "node:module";
|
|
20
|
+
import { tmpdir } from "node:os";
|
|
21
|
+
import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
22
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
23
|
+
import { promisify } from "node:util";
|
|
24
|
+
|
|
25
|
+
const run = promisify(execFile);
|
|
26
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
27
|
+
export const CUES_VERSION = 1;
|
|
28
|
+
const MAX_CUES = 2000;
|
|
29
|
+
const MAX_AIR_SAMPLES = 50 * 60 * 15;
|
|
30
|
+
const MAX_DOM_BYTES = 64 * 1024 * 1024;
|
|
31
|
+
|
|
32
|
+
const TYPES = {
|
|
33
|
+
".html": "text/html; charset=utf-8",
|
|
34
|
+
".js": "text/javascript",
|
|
35
|
+
".mjs": "text/javascript",
|
|
36
|
+
".css": "text/css",
|
|
37
|
+
".json": "application/json",
|
|
38
|
+
".svg": "image/svg+xml",
|
|
39
|
+
".png": "image/png",
|
|
40
|
+
".jpg": "image/jpeg",
|
|
41
|
+
".jpeg": "image/jpeg",
|
|
42
|
+
".webp": "image/webp",
|
|
43
|
+
".gif": "image/gif",
|
|
44
|
+
".woff2": "font/woff2",
|
|
45
|
+
".woff": "font/woff",
|
|
46
|
+
".ttf": "font/ttf",
|
|
47
|
+
".otf": "font/otf",
|
|
48
|
+
".mp4": "video/mp4",
|
|
49
|
+
".webm": "video/webm",
|
|
50
|
+
".wav": "audio/wav",
|
|
51
|
+
".mp3": "audio/mpeg",
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const ENTITIES = { quot: '"', amp: "&", lt: "<", gt: ">", apos: "'", "#39": "'", "#34": '"' };
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Validate one cue list as the kit writes it.
|
|
58
|
+
* @param {unknown} list
|
|
59
|
+
* @returns {{ t: number; sfx: string; gain: number; pan: number; send?: number; name?: string }[]}
|
|
60
|
+
*/
|
|
61
|
+
export function validateCues(list) {
|
|
62
|
+
if (!Array.isArray(list)) throw new Error("cues must be a list");
|
|
63
|
+
if (list.length > MAX_CUES) throw new Error(`more than ${MAX_CUES} cues`);
|
|
64
|
+
return list.map((cue, index) => {
|
|
65
|
+
if (!cue || typeof cue !== "object") throw new Error(`cue ${index} is not an object`);
|
|
66
|
+
const { t, sfx, gain = 1, pan = 0, send, name } = cue;
|
|
67
|
+
if (!(typeof t === "number" && Number.isFinite(t) && t >= 0))
|
|
68
|
+
throw new Error(`cue ${index}: t must be a time >= 0`);
|
|
69
|
+
if (typeof sfx !== "string" || !/^[a-z][a-z-]*$/.test(sfx))
|
|
70
|
+
throw new Error(`cue ${index}: sfx must be a sound name`);
|
|
71
|
+
if (!(typeof gain === "number" && gain >= 0 && gain <= 2))
|
|
72
|
+
throw new Error(`cue ${index}: gain must be 0..2`);
|
|
73
|
+
if (!(typeof pan === "number" && pan >= -1 && pan <= 1))
|
|
74
|
+
throw new Error(`cue ${index}: pan must be -1..1`);
|
|
75
|
+
if (send !== undefined && !(typeof send === "number" && send >= 0 && send <= 1))
|
|
76
|
+
throw new Error(`cue ${index}: send must be 0..1`);
|
|
77
|
+
if (name !== undefined && typeof name !== "string")
|
|
78
|
+
throw new Error(`cue ${index}: name must be text`);
|
|
79
|
+
return {
|
|
80
|
+
t,
|
|
81
|
+
sfx,
|
|
82
|
+
gain,
|
|
83
|
+
pan,
|
|
84
|
+
...(send === undefined ? {} : { send }),
|
|
85
|
+
...(name ? { name: name.slice(0, 60) } : {}),
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Validate the camera's speed curve as the kit writes it.
|
|
92
|
+
* @param {unknown} curve
|
|
93
|
+
* @returns {{ rate: number; start: number; values: number[] }}
|
|
94
|
+
*/
|
|
95
|
+
export function validateAir(curve) {
|
|
96
|
+
if (!curve || typeof curve !== "object") throw new Error("air must be an object");
|
|
97
|
+
const { rate, start, values } = /** @type {Record<string, unknown>} */ (curve);
|
|
98
|
+
if (!(typeof rate === "number" && rate >= 10 && rate <= 240))
|
|
99
|
+
throw new Error("air: rate must be 10..240");
|
|
100
|
+
if (!(typeof start === "number" && Number.isFinite(start) && start >= 0))
|
|
101
|
+
throw new Error("air: start must be a time >= 0");
|
|
102
|
+
if (!Array.isArray(values) || values.length > MAX_AIR_SAMPLES)
|
|
103
|
+
throw new Error(`air: values must be a list of at most ${MAX_AIR_SAMPLES} samples`);
|
|
104
|
+
if (!values.every((v) => typeof v === "number" && Number.isFinite(v) && v >= 0))
|
|
105
|
+
throw new Error("air: every value must be a speed >= 0");
|
|
106
|
+
return { rate, start, values };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Read a JSON attribute the kit wrote on the root <html> element, or null. */
|
|
110
|
+
function readRootAttribute(dom, attribute, label) {
|
|
111
|
+
// Chrome escapes `&` and `"` in attribute values but not `<` or `>`, so skip
|
|
112
|
+
// over quoted values instead of stopping at the first `>`.
|
|
113
|
+
const tag = /<html\b(?:[^>"']|"[^"]*"|'[^']*')*>/i.exec(dom)?.[0] ?? "";
|
|
114
|
+
const match = new RegExp(`\\s${attribute}="([^"]*)"`).exec(tag);
|
|
115
|
+
if (!match) return null;
|
|
116
|
+
const json = (match[1] ?? "").replace(/&(quot|amp|lt|gt|apos|#39|#34);/g, (_, e) => ENTITIES[e]);
|
|
117
|
+
try {
|
|
118
|
+
return { value: JSON.parse(json) };
|
|
119
|
+
} catch {
|
|
120
|
+
throw new Error(`the page wrote an unreadable ${label}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* The camera speed curve a loaded page wrote, or null without a kit camera.
|
|
126
|
+
* @param {string} dom serialized DOM
|
|
127
|
+
*/
|
|
128
|
+
export function readAir(dom) {
|
|
129
|
+
const found = readRootAttribute(dom, "data-ez-air", "camera curve");
|
|
130
|
+
return found ? validateAir(found.value) : null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* The cue list a loaded page wrote on its root element, or null when the
|
|
135
|
+
* composition marked none.
|
|
136
|
+
* @param {string} dom serialized DOM, as `chrome --dump-dom` prints it
|
|
137
|
+
*/
|
|
138
|
+
export function readCues(dom) {
|
|
139
|
+
const found = readRootAttribute(dom, "data-ez-cues", "cue list");
|
|
140
|
+
return found ? validateCues(found.value) : null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Serve `root` read-only on 127.0.0.1; never outside it. */
|
|
144
|
+
export async function serve(root) {
|
|
145
|
+
const base = await realpath(root);
|
|
146
|
+
const server = createServer(async (request, response) => {
|
|
147
|
+
try {
|
|
148
|
+
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
149
|
+
response.writeHead(405).end();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const path = decodeURIComponent(new URL(request.url ?? "/", "http://127.0.0.1").pathname);
|
|
153
|
+
const file = await realpath(resolve(base, `.${path}`));
|
|
154
|
+
const inside = relative(base, file);
|
|
155
|
+
if (inside.startsWith("..") || isAbsolute(inside) || !(await stat(file)).isFile()) {
|
|
156
|
+
response.writeHead(404).end();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
response.writeHead(200, {
|
|
160
|
+
"content-type": TYPES[extname(file).toLowerCase()] ?? "application/octet-stream",
|
|
161
|
+
});
|
|
162
|
+
if (request.method === "HEAD") response.end();
|
|
163
|
+
else createReadStream(file).pipe(response);
|
|
164
|
+
} catch {
|
|
165
|
+
response.writeHead(404).end();
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
await new Promise((resolveListen, reject) => {
|
|
169
|
+
server.once("error", reject);
|
|
170
|
+
server.listen(0, "127.0.0.1", resolveListen);
|
|
171
|
+
});
|
|
172
|
+
const address = server.address();
|
|
173
|
+
if (!address || typeof address === "string") throw new Error("Could not start the page server");
|
|
174
|
+
return { server, port: address.port };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export async function chromePath() {
|
|
178
|
+
const override = process.env.EZ_MOTION_CHROME?.trim();
|
|
179
|
+
if (override) return resolve(override);
|
|
180
|
+
try {
|
|
181
|
+
const { stdout } = await run(
|
|
182
|
+
process.execPath,
|
|
183
|
+
[join(here, "hyperframes.mjs"), "browser", "path"],
|
|
184
|
+
{
|
|
185
|
+
timeout: 60_000,
|
|
186
|
+
windowsHide: true,
|
|
187
|
+
},
|
|
188
|
+
);
|
|
189
|
+
const found = stdout.trim().split(/\r?\n/).at(-1)?.trim();
|
|
190
|
+
if (found) return found;
|
|
191
|
+
} catch {
|
|
192
|
+
/* fall through to the instruction below */
|
|
193
|
+
}
|
|
194
|
+
throw new Error("Chrome for HyperFrames is missing; run `hf browser ensure` first");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** The puppeteer-core HyperFrames itself drives Chrome with. */
|
|
198
|
+
async function loadPuppeteer() {
|
|
199
|
+
const fromHere = createRequire(import.meta.url);
|
|
200
|
+
const fromHyperframes = createRequire(fromHere.resolve("hyperframes/package.json"));
|
|
201
|
+
const mod = await import(pathToFileURL(fromHyperframes.resolve("puppeteer-core")).href);
|
|
202
|
+
return mod.default ?? mod;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Load the page in headless Chrome and return its DOM after the script ran. */
|
|
206
|
+
async function dumpDom(chrome, url, signal) {
|
|
207
|
+
const puppeteer = await loadPuppeteer();
|
|
208
|
+
const profile = await mkdtemp(join(tmpdir(), "ez-motion-cues-"));
|
|
209
|
+
let browser;
|
|
210
|
+
try {
|
|
211
|
+
browser = await puppeteer.launch({
|
|
212
|
+
executablePath: chrome,
|
|
213
|
+
headless: /chrome-headless-shell/i.test(basename(chrome)) ? "shell" : true,
|
|
214
|
+
userDataDir: profile,
|
|
215
|
+
// Linux CI containers often lack the user namespaces Chrome's sandbox needs.
|
|
216
|
+
args: [
|
|
217
|
+
"--disable-gpu",
|
|
218
|
+
"--mute-audio",
|
|
219
|
+
...(process.platform === "linux" ? ["--no-sandbox"] : []),
|
|
220
|
+
],
|
|
221
|
+
handleSIGINT: false,
|
|
222
|
+
handleSIGTERM: false,
|
|
223
|
+
handleSIGHUP: false,
|
|
224
|
+
timeout: 60_000,
|
|
225
|
+
signal,
|
|
226
|
+
});
|
|
227
|
+
const page = await browser.newPage();
|
|
228
|
+
page.setDefaultTimeout(60_000);
|
|
229
|
+
await page.goto(url, { waitUntil: "load" });
|
|
230
|
+
// Timelines may be built after fonts load (the documented async setup) and
|
|
231
|
+
// are registered last; the kit writes its cues in a microtask after that.
|
|
232
|
+
await page.evaluate(async () => {
|
|
233
|
+
await document.fonts.ready;
|
|
234
|
+
});
|
|
235
|
+
await page
|
|
236
|
+
.waitForFunction(() => Object.keys(window.__timelines ?? {}).length > 0, { timeout: 8000 })
|
|
237
|
+
.catch(() => undefined);
|
|
238
|
+
await page.evaluate(() => new Promise((done) => setTimeout(done, 0)));
|
|
239
|
+
const dom = await page.content();
|
|
240
|
+
if (!dom) throw new Error("empty page");
|
|
241
|
+
return dom.slice(0, MAX_DOM_BYTES);
|
|
242
|
+
} catch (error) {
|
|
243
|
+
if (signal?.aborted) throw new Error("cancelled");
|
|
244
|
+
throw new Error(
|
|
245
|
+
`Chrome could not load the page: ${error instanceof Error ? error.message : String(error)}`,
|
|
246
|
+
);
|
|
247
|
+
} finally {
|
|
248
|
+
await browser?.close().catch(() => undefined);
|
|
249
|
+
await rm(profile, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function parseArgs(argv) {
|
|
254
|
+
const [project, ...rest] = argv;
|
|
255
|
+
if (!project || project.startsWith("--"))
|
|
256
|
+
throw new Error(
|
|
257
|
+
"usage: cues.mjs <project-dir> [--out <cues.json>] [--composition <file.html>]",
|
|
258
|
+
);
|
|
259
|
+
const options = { project: resolve(project), composition: "index.html", out: "" };
|
|
260
|
+
for (let index = 0; index < rest.length; index += 2) {
|
|
261
|
+
const flag = rest[index];
|
|
262
|
+
const value = rest[index + 1];
|
|
263
|
+
if (value === undefined || value.startsWith("--")) throw new Error(`${flag} needs a value`);
|
|
264
|
+
if (flag === "--out") options.out = resolve(value);
|
|
265
|
+
else if (flag === "--composition") options.composition = value;
|
|
266
|
+
else throw new Error(`Unsupported option ${flag}`);
|
|
267
|
+
}
|
|
268
|
+
options.out ||= join(options.project, "cues.json");
|
|
269
|
+
return options;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
async function main() {
|
|
273
|
+
const started = performance.now();
|
|
274
|
+
const options = parseArgs(process.argv.slice(2));
|
|
275
|
+
if (!(await stat(options.project).catch(() => null))?.isDirectory())
|
|
276
|
+
throw new Error("Expected a project folder");
|
|
277
|
+
const page = resolve(options.project, options.composition);
|
|
278
|
+
if (!page.startsWith(options.project + sep) || extname(page).toLowerCase() !== ".html")
|
|
279
|
+
throw new Error("--composition must be an .html file inside the project");
|
|
280
|
+
if (!(await stat(page).catch(() => null))?.isFile())
|
|
281
|
+
throw new Error(`${options.composition} not found`);
|
|
282
|
+
const chrome = await chromePath();
|
|
283
|
+
const controller = new AbortController();
|
|
284
|
+
const abort = () => controller.abort();
|
|
285
|
+
process.once("SIGTERM", abort);
|
|
286
|
+
process.once("SIGINT", abort);
|
|
287
|
+
const { server, port } = await serve(options.project);
|
|
288
|
+
try {
|
|
289
|
+
const route = relative(options.project, page).split(sep).map(encodeURIComponent).join("/");
|
|
290
|
+
const dom = await dumpDom(chrome, `http://127.0.0.1:${port}/${route}`, controller.signal);
|
|
291
|
+
const cues = readCues(dom);
|
|
292
|
+
const air = readAir(dom);
|
|
293
|
+
// A plain page load does not mount sub-composition files, so their scripts never run.
|
|
294
|
+
const unloaded = (dom.match(/\sdata-composition-src=/g) ?? []).length;
|
|
295
|
+
const note = unloaded
|
|
296
|
+
? `${unloaded} sub-composition file(s) were not loaded; cues marked inside them are missing. Mark cues in the root composition's script.`
|
|
297
|
+
: undefined;
|
|
298
|
+
if (!cues && !air)
|
|
299
|
+
throw new Error(
|
|
300
|
+
`The composition marked no cues. Load the kit and call kit.cue(tl, at, sfx) where each sound belongs.${note ? ` ${note}` : ""}`,
|
|
301
|
+
);
|
|
302
|
+
const file = {
|
|
303
|
+
version: CUES_VERSION,
|
|
304
|
+
composition: options.composition,
|
|
305
|
+
cues: cues ?? [],
|
|
306
|
+
...(air ? { air } : {}),
|
|
307
|
+
};
|
|
308
|
+
await writeFile(options.out, `${JSON.stringify(file, null, 2)}\n`);
|
|
309
|
+
process.stdout.write(
|
|
310
|
+
`${JSON.stringify({
|
|
311
|
+
ok: true,
|
|
312
|
+
out: options.out,
|
|
313
|
+
cues: file.cues.length,
|
|
314
|
+
sounds: [...new Set(file.cues.map((cue) => cue.sfx))].sort(),
|
|
315
|
+
...(air ? { cameraAir: true } : {}),
|
|
316
|
+
...(note ? { note } : {}),
|
|
317
|
+
elapsedMs: Math.round(performance.now() - started),
|
|
318
|
+
})}\n`,
|
|
319
|
+
);
|
|
320
|
+
} finally {
|
|
321
|
+
process.removeListener("SIGTERM", abort);
|
|
322
|
+
process.removeListener("SIGINT", abort);
|
|
323
|
+
server.closeAllConnections();
|
|
324
|
+
server.close();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
|
|
329
|
+
try {
|
|
330
|
+
await main();
|
|
331
|
+
} catch (error) {
|
|
332
|
+
process.stderr.write(
|
|
333
|
+
`Cue export failed: ${error instanceof Error ? error.message : "invalid input"}\n`,
|
|
334
|
+
);
|
|
335
|
+
process.exitCode = 1;
|
|
336
|
+
}
|
|
337
|
+
}
|