@kenkaiiii/gg-editor 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +64 -1
- package/dist/cli.js.map +1 -1
- package/dist/core/audio-mix.d.ts.map +1 -1
- package/dist/core/audio-mix.js +8 -1
- package/dist/core/audio-mix.js.map +1 -1
- package/dist/core/audio-mix.test.js +1 -1
- package/dist/core/audio-mix.test.js.map +1 -1
- package/dist/core/auth/api-keys.d.ts +1 -1
- package/dist/core/auth/api-keys.d.ts.map +1 -1
- package/dist/core/auth/api-keys.js +2 -1
- package/dist/core/auth/api-keys.js.map +1 -1
- package/dist/core/auth/login.d.ts.map +1 -1
- package/dist/core/auth/login.js.map +1 -1
- package/dist/core/beats.d.ts +59 -0
- package/dist/core/beats.d.ts.map +1 -0
- package/dist/core/beats.js +122 -0
- package/dist/core/beats.js.map +1 -0
- package/dist/core/beats.test.d.ts +2 -0
- package/dist/core/beats.test.d.ts.map +1 -0
- package/dist/core/beats.test.js +86 -0
- package/dist/core/beats.test.js.map +1 -0
- package/dist/core/brand-kit.d.ts +80 -0
- package/dist/core/brand-kit.d.ts.map +1 -0
- package/dist/core/brand-kit.js +96 -0
- package/dist/core/brand-kit.js.map +1 -0
- package/dist/core/brand-kit.test.d.ts +2 -0
- package/dist/core/brand-kit.test.d.ts.map +1 -0
- package/dist/core/brand-kit.test.js +76 -0
- package/dist/core/brand-kit.test.js.map +1 -0
- package/dist/core/bundled-sfx.d.ts +64 -0
- package/dist/core/bundled-sfx.d.ts.map +1 -0
- package/dist/core/bundled-sfx.js +218 -0
- package/dist/core/bundled-sfx.js.map +1 -0
- package/dist/core/bundled-sfx.test.d.ts +2 -0
- package/dist/core/bundled-sfx.test.d.ts.map +1 -0
- package/dist/core/bundled-sfx.test.js +81 -0
- package/dist/core/bundled-sfx.test.js.map +1 -0
- package/dist/core/child-abort.d.ts +57 -0
- package/dist/core/child-abort.d.ts.map +1 -0
- package/dist/core/child-abort.js +95 -0
- package/dist/core/child-abort.js.map +1 -0
- package/dist/core/child-abort.test.d.ts +2 -0
- package/dist/core/child-abort.test.d.ts.map +1 -0
- package/dist/core/child-abort.test.js +88 -0
- package/dist/core/child-abort.test.js.map +1 -0
- package/dist/core/clip-scoring.d.ts +44 -0
- package/dist/core/clip-scoring.d.ts.map +1 -0
- package/dist/core/clip-scoring.js +165 -0
- package/dist/core/clip-scoring.js.map +1 -0
- package/dist/core/clip-scoring.test.d.ts +2 -0
- package/dist/core/clip-scoring.test.d.ts.map +1 -0
- package/dist/core/clip-scoring.test.js +113 -0
- package/dist/core/clip-scoring.test.js.map +1 -0
- package/dist/core/emoji-captions.d.ts +45 -0
- package/dist/core/emoji-captions.d.ts.map +1 -0
- package/dist/core/emoji-captions.js +121 -0
- package/dist/core/emoji-captions.js.map +1 -0
- package/dist/core/face-reframe.d.ts +91 -0
- package/dist/core/face-reframe.d.ts.map +1 -0
- package/dist/core/face-reframe.js +141 -0
- package/dist/core/face-reframe.js.map +1 -0
- package/dist/core/face-reframe.test.d.ts +2 -0
- package/dist/core/face-reframe.test.d.ts.map +1 -0
- package/dist/core/face-reframe.test.js +171 -0
- package/dist/core/face-reframe.test.js.map +1 -0
- package/dist/core/filler-words.d.ts +57 -9
- package/dist/core/filler-words.d.ts.map +1 -1
- package/dist/core/filler-words.js +61 -9
- package/dist/core/filler-words.js.map +1 -1
- package/dist/core/filler-words.test.js +91 -17
- package/dist/core/filler-words.test.js.map +1 -1
- package/dist/core/hook-rewrite.d.ts +48 -0
- package/dist/core/hook-rewrite.d.ts.map +1 -0
- package/dist/core/hook-rewrite.js +151 -0
- package/dist/core/hook-rewrite.js.map +1 -0
- package/dist/core/hook-rewrite.test.d.ts +2 -0
- package/dist/core/hook-rewrite.test.d.ts.map +1 -0
- package/dist/core/hook-rewrite.test.js +58 -0
- package/dist/core/hook-rewrite.test.js.map +1 -0
- package/dist/core/hosts/lazy.d.ts.map +1 -1
- package/dist/core/hosts/lazy.js +2 -0
- package/dist/core/hosts/lazy.js.map +1 -1
- package/dist/core/hosts/premiere/adapter.d.ts +1 -0
- package/dist/core/hosts/premiere/adapter.d.ts.map +1 -1
- package/dist/core/hosts/premiere/adapter.js.map +1 -1
- package/dist/core/hosts/premiere/bridge-source.d.ts.map +1 -1
- package/dist/core/hosts/premiere/bridge-source.js +6 -3
- package/dist/core/hosts/premiere/bridge-source.js.map +1 -1
- package/dist/core/hosts/resolve/adapter.d.ts +1 -0
- package/dist/core/hosts/resolve/adapter.d.ts.map +1 -1
- package/dist/core/hosts/resolve/adapter.js.map +1 -1
- package/dist/core/hosts/resolve/bridge-source.d.ts.map +1 -1
- package/dist/core/hosts/resolve/bridge-source.js +31 -4
- package/dist/core/hosts/resolve/bridge-source.js.map +1 -1
- package/dist/core/hosts/resolve/bridge.d.ts +2 -19
- package/dist/core/hosts/resolve/bridge.d.ts.map +1 -1
- package/dist/core/hosts/resolve/bridge.js +70 -41
- package/dist/core/hosts/resolve/bridge.js.map +1 -1
- package/dist/core/hosts/resolve/bridge.test.js +130 -0
- package/dist/core/hosts/resolve/bridge.test.js.map +1 -1
- package/dist/core/hosts/types.d.ts +6 -0
- package/dist/core/hosts/types.d.ts.map +1 -1
- package/dist/core/hosts/types.js.map +1 -1
- package/dist/core/logger.d.ts +32 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +188 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/loop-match.d.ts +57 -0
- package/dist/core/loop-match.d.ts.map +1 -0
- package/dist/core/loop-match.js +91 -0
- package/dist/core/loop-match.js.map +1 -0
- package/dist/core/media/ffmpeg.d.ts.map +1 -1
- package/dist/core/media/ffmpeg.js +14 -3
- package/dist/core/media/ffmpeg.js.map +1 -1
- package/dist/core/multi-format.d.ts +67 -0
- package/dist/core/multi-format.d.ts.map +1 -0
- package/dist/core/multi-format.js +127 -0
- package/dist/core/multi-format.js.map +1 -0
- package/dist/core/multi-format.test.d.ts +2 -0
- package/dist/core/multi-format.test.d.ts.map +1 -0
- package/dist/core/multi-format.test.js +151 -0
- package/dist/core/multi-format.test.js.map +1 -0
- package/dist/core/python/beats.py +61 -0
- package/dist/core/python/face_reframe.py +163 -0
- package/dist/core/python/sidecar-path.d.ts +13 -0
- package/dist/core/python/sidecar-path.d.ts.map +1 -0
- package/dist/core/python/sidecar-path.js +24 -0
- package/dist/core/python/sidecar-path.js.map +1 -0
- package/dist/core/python.d.ts +57 -0
- package/dist/core/python.d.ts.map +1 -0
- package/dist/core/python.js +107 -0
- package/dist/core/python.js.map +1 -0
- package/dist/core/python.test.d.ts +2 -0
- package/dist/core/python.test.d.ts.map +1 -0
- package/dist/core/python.test.js +129 -0
- package/dist/core/python.test.js.map +1 -0
- package/dist/core/retention-structure.d.ts +81 -0
- package/dist/core/retention-structure.d.ts.map +1 -0
- package/dist/core/retention-structure.js +206 -0
- package/dist/core/retention-structure.js.map +1 -0
- package/dist/core/retention-structure.test.d.ts +2 -0
- package/dist/core/retention-structure.test.d.ts.map +1 -0
- package/dist/core/retention-structure.test.js +88 -0
- package/dist/core/retention-structure.test.js.map +1 -0
- package/dist/core/review.d.ts +17 -0
- package/dist/core/review.d.ts.map +1 -1
- package/dist/core/review.js +20 -24
- package/dist/core/review.js.map +1 -1
- package/dist/core/safe-paths.d.ts +11 -0
- package/dist/core/safe-paths.d.ts.map +1 -1
- package/dist/core/safe-paths.js +26 -10
- package/dist/core/safe-paths.js.map +1 -1
- package/dist/core/safe-paths.test.js +16 -0
- package/dist/core/safe-paths.test.js.map +1 -1
- package/dist/core/skills-loader.d.ts +48 -2
- package/dist/core/skills-loader.d.ts.map +1 -1
- package/dist/core/skills-loader.js +97 -19
- package/dist/core/skills-loader.js.map +1 -1
- package/dist/core/skills-loader.test.js +63 -1
- package/dist/core/skills-loader.test.js.map +1 -1
- package/dist/core/srt.d.ts +42 -7
- package/dist/core/srt.d.ts.map +1 -1
- package/dist/core/srt.js +101 -32
- package/dist/core/srt.js.map +1 -1
- package/dist/core/srt.test.js +54 -1
- package/dist/core/srt.test.js.map +1 -1
- package/dist/core/thumbnail-compose.d.ts +58 -0
- package/dist/core/thumbnail-compose.d.ts.map +1 -0
- package/dist/core/thumbnail-compose.js +101 -0
- package/dist/core/thumbnail-compose.js.map +1 -0
- package/dist/core/thumbnail-promise.d.ts +46 -0
- package/dist/core/thumbnail-promise.d.ts.map +1 -0
- package/dist/core/thumbnail-promise.js +133 -0
- package/dist/core/thumbnail-promise.js.map +1 -0
- package/dist/core/thumbnail-promise.test.d.ts +2 -0
- package/dist/core/thumbnail-promise.test.d.ts.map +1 -0
- package/dist/core/thumbnail-promise.test.js +52 -0
- package/dist/core/thumbnail-promise.test.js.map +1 -0
- package/dist/core/viral-moments.d.ts +70 -0
- package/dist/core/viral-moments.d.ts.map +1 -0
- package/dist/core/viral-moments.js +192 -0
- package/dist/core/viral-moments.js.map +1 -0
- package/dist/core/viral-moments.test.d.ts +2 -0
- package/dist/core/viral-moments.test.d.ts.map +1 -0
- package/dist/core/viral-moments.test.js +153 -0
- package/dist/core/viral-moments.test.js.map +1 -0
- package/dist/core/whisper.d.ts +16 -0
- package/dist/core/whisper.d.ts.map +1 -1
- package/dist/core/whisper.js +72 -5
- package/dist/core/whisper.js.map +1 -1
- package/dist/core/whisper.test.js +111 -1
- package/dist/core/whisper.test.js.map +1 -1
- package/dist/core/youtube-metadata.d.ts +44 -0
- package/dist/core/youtube-metadata.d.ts.map +1 -0
- package/dist/core/youtube-metadata.js +168 -0
- package/dist/core/youtube-metadata.js.map +1 -0
- package/dist/core/youtube-metadata.test.d.ts +2 -0
- package/dist/core/youtube-metadata.test.d.ts.map +1 -0
- package/dist/core/youtube-metadata.test.js +132 -0
- package/dist/core/youtube-metadata.test.js.map +1 -0
- package/dist/prompt-commands.d.ts +24 -0
- package/dist/prompt-commands.d.ts.map +1 -0
- package/dist/prompt-commands.js +243 -0
- package/dist/prompt-commands.js.map +1 -0
- package/dist/prompt-commands.test.d.ts +2 -0
- package/dist/prompt-commands.test.d.ts.map +1 -0
- package/dist/prompt-commands.test.js +46 -0
- package/dist/prompt-commands.test.js.map +1 -0
- package/dist/skills.d.ts +6 -6
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +1426 -445
- package/dist/skills.js.map +1 -1
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +108 -0
- package/dist/system-prompt.js.map +1 -1
- package/dist/tools/add-fades.d.ts.map +1 -1
- package/dist/tools/add-fades.js +2 -1
- package/dist/tools/add-fades.js.map +1 -1
- package/dist/tools/add-sfx-at-cuts.d.ts.map +1 -1
- package/dist/tools/add-sfx-at-cuts.js +36 -11
- package/dist/tools/add-sfx-at-cuts.js.map +1 -1
- package/dist/tools/add-sfx-to-timeline.d.ts +34 -0
- package/dist/tools/add-sfx-to-timeline.d.ts.map +1 -0
- package/dist/tools/add-sfx-to-timeline.js +169 -0
- package/dist/tools/add-sfx-to-timeline.js.map +1 -0
- package/dist/tools/add-sfx-to-timeline.test.d.ts +2 -0
- package/dist/tools/add-sfx-to-timeline.test.d.ts.map +1 -0
- package/dist/tools/add-sfx-to-timeline.test.js +181 -0
- package/dist/tools/add-sfx-to-timeline.test.js.map +1 -0
- package/dist/tools/audit-first-frame.d.ts +36 -0
- package/dist/tools/audit-first-frame.d.ts.map +1 -0
- package/dist/tools/audit-first-frame.js +181 -0
- package/dist/tools/audit-first-frame.js.map +1 -0
- package/dist/tools/audit-retention-structure.d.ts +20 -0
- package/dist/tools/audit-retention-structure.d.ts.map +1 -0
- package/dist/tools/audit-retention-structure.js +95 -0
- package/dist/tools/audit-retention-structure.js.map +1 -0
- package/dist/tools/audit-retention-structure.test.d.ts +2 -0
- package/dist/tools/audit-retention-structure.test.d.ts.map +1 -0
- package/dist/tools/audit-retention-structure.test.js +93 -0
- package/dist/tools/audit-retention-structure.test.js.map +1 -0
- package/dist/tools/bleep-words.d.ts +59 -0
- package/dist/tools/bleep-words.d.ts.map +1 -0
- package/dist/tools/bleep-words.js +211 -0
- package/dist/tools/bleep-words.js.map +1 -0
- package/dist/tools/bleep-words.test.d.ts +2 -0
- package/dist/tools/bleep-words.test.d.ts.map +1 -0
- package/dist/tools/bleep-words.test.js +96 -0
- package/dist/tools/bleep-words.test.js.map +1 -0
- package/dist/tools/burn-subtitles.d.ts.map +1 -1
- package/dist/tools/burn-subtitles.js +10 -5
- package/dist/tools/burn-subtitles.js.map +1 -1
- package/dist/tools/clean-audio.d.ts.map +1 -1
- package/dist/tools/clean-audio.js +2 -1
- package/dist/tools/clean-audio.js.map +1 -1
- package/dist/tools/cluster-takes.js +2 -1
- package/dist/tools/cluster-takes.js.map +1 -1
- package/dist/tools/compose-thumbnail-variants.d.ts +70 -0
- package/dist/tools/compose-thumbnail-variants.d.ts.map +1 -0
- package/dist/tools/compose-thumbnail-variants.js +274 -0
- package/dist/tools/compose-thumbnail-variants.js.map +1 -0
- package/dist/tools/compose-thumbnail.d.ts +6 -13
- package/dist/tools/compose-thumbnail.d.ts.map +1 -1
- package/dist/tools/compose-thumbnail.js +44 -81
- package/dist/tools/compose-thumbnail.js.map +1 -1
- package/dist/tools/concat-videos.d.ts.map +1 -1
- package/dist/tools/concat-videos.js +12 -5
- package/dist/tools/concat-videos.js.map +1 -1
- package/dist/tools/concat-videos.test.d.ts +2 -0
- package/dist/tools/concat-videos.test.d.ts.map +1 -0
- package/dist/tools/concat-videos.test.js +103 -0
- package/dist/tools/concat-videos.test.js.map +1 -0
- package/dist/tools/crossfade-videos.d.ts.map +1 -1
- package/dist/tools/crossfade-videos.js +2 -1
- package/dist/tools/crossfade-videos.js.map +1 -1
- package/dist/tools/cut-filler-words.d.ts.map +1 -1
- package/dist/tools/cut-filler-words.js +24 -8
- package/dist/tools/cut-filler-words.js.map +1 -1
- package/dist/tools/detect-speaker-changes.js +2 -1
- package/dist/tools/detect-speaker-changes.js.map +1 -1
- package/dist/tools/extract-audio.d.ts.map +1 -1
- package/dist/tools/extract-audio.js +13 -7
- package/dist/tools/extract-audio.js.map +1 -1
- package/dist/tools/face-reframe.d.ts +30 -0
- package/dist/tools/face-reframe.d.ts.map +1 -0
- package/dist/tools/face-reframe.js +143 -0
- package/dist/tools/face-reframe.js.map +1 -0
- package/dist/tools/face-reframe.test.d.ts +2 -0
- package/dist/tools/face-reframe.test.d.ts.map +1 -0
- package/dist/tools/face-reframe.test.js +139 -0
- package/dist/tools/face-reframe.test.js.map +1 -0
- package/dist/tools/find-viral-moments.d.ts +23 -0
- package/dist/tools/find-viral-moments.d.ts.map +1 -0
- package/dist/tools/find-viral-moments.js +176 -0
- package/dist/tools/find-viral-moments.js.map +1 -0
- package/dist/tools/find-viral-moments.test.d.ts +2 -0
- package/dist/tools/find-viral-moments.test.d.ts.map +1 -0
- package/dist/tools/find-viral-moments.test.js +144 -0
- package/dist/tools/find-viral-moments.test.js.map +1 -0
- package/dist/tools/generate-gif.d.ts.map +1 -1
- package/dist/tools/generate-gif.js +47 -40
- package/dist/tools/generate-gif.js.map +1 -1
- package/dist/tools/generate-gif.test.d.ts +2 -0
- package/dist/tools/generate-gif.test.d.ts.map +1 -0
- package/dist/tools/generate-gif.test.js +115 -0
- package/dist/tools/generate-gif.test.js.map +1 -0
- package/dist/tools/generate-outro.d.ts +18 -0
- package/dist/tools/generate-outro.d.ts.map +1 -0
- package/dist/tools/generate-outro.js +175 -0
- package/dist/tools/generate-outro.js.map +1 -0
- package/dist/tools/generate-youtube-metadata.d.ts +23 -0
- package/dist/tools/generate-youtube-metadata.d.ts.map +1 -0
- package/dist/tools/generate-youtube-metadata.js +103 -0
- package/dist/tools/generate-youtube-metadata.js.map +1 -0
- package/dist/tools/generate-youtube-metadata.test.d.ts +2 -0
- package/dist/tools/generate-youtube-metadata.test.d.ts.map +1 -0
- package/dist/tools/generate-youtube-metadata.test.js +118 -0
- package/dist/tools/generate-youtube-metadata.test.js.map +1 -0
- package/dist/tools/index.d.ts +14 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +130 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/index.test.js +27 -1
- package/dist/tools/index.test.js.map +1 -1
- package/dist/tools/ken-burns.d.ts.map +1 -1
- package/dist/tools/ken-burns.js +2 -1
- package/dist/tools/ken-burns.js.map +1 -1
- package/dist/tools/loop-match-short.d.ts +22 -0
- package/dist/tools/loop-match-short.d.ts.map +1 -0
- package/dist/tools/loop-match-short.js +107 -0
- package/dist/tools/loop-match-short.js.map +1 -0
- package/dist/tools/mix-audio.d.ts.map +1 -1
- package/dist/tools/mix-audio.js +2 -1
- package/dist/tools/mix-audio.js.map +1 -1
- package/dist/tools/normalize-loudness.d.ts.map +1 -1
- package/dist/tools/normalize-loudness.js +2 -1
- package/dist/tools/normalize-loudness.js.map +1 -1
- package/dist/tools/path-traversal.test.d.ts +15 -0
- package/dist/tools/path-traversal.test.d.ts.map +1 -0
- package/dist/tools/path-traversal.test.js +223 -0
- package/dist/tools/path-traversal.test.js.map +1 -0
- package/dist/tools/pick-best-takes.js +2 -1
- package/dist/tools/pick-best-takes.js.map +1 -1
- package/dist/tools/punch-in.d.ts.map +1 -1
- package/dist/tools/punch-in.js +2 -1
- package/dist/tools/punch-in.js.map +1 -1
- package/dist/tools/read-transcript.js +2 -1
- package/dist/tools/read-transcript.js.map +1 -1
- package/dist/tools/render-multi-format.d.ts +35 -0
- package/dist/tools/render-multi-format.d.ts.map +1 -0
- package/dist/tools/render-multi-format.js +206 -0
- package/dist/tools/render-multi-format.js.map +1 -0
- package/dist/tools/render-multi-format.test.d.ts +2 -0
- package/dist/tools/render-multi-format.test.d.ts.map +1 -0
- package/dist/tools/render-multi-format.test.js +312 -0
- package/dist/tools/render-multi-format.test.js.map +1 -0
- package/dist/tools/render.d.ts.map +1 -1
- package/dist/tools/render.js +2 -2
- package/dist/tools/render.js.map +1 -1
- package/dist/tools/rewrite-hook.d.ts +32 -0
- package/dist/tools/rewrite-hook.d.ts.map +1 -0
- package/dist/tools/rewrite-hook.js +65 -0
- package/dist/tools/rewrite-hook.js.map +1 -0
- package/dist/tools/score-clip.d.ts +30 -0
- package/dist/tools/score-clip.d.ts.map +1 -0
- package/dist/tools/score-clip.js +109 -0
- package/dist/tools/score-clip.js.map +1 -0
- package/dist/tools/score-clip.test.d.ts +2 -0
- package/dist/tools/score-clip.test.d.ts.map +1 -0
- package/dist/tools/score-clip.test.js +110 -0
- package/dist/tools/score-clip.test.js.map +1 -0
- package/dist/tools/search-tools.d.ts +34 -0
- package/dist/tools/search-tools.d.ts.map +1 -0
- package/dist/tools/search-tools.js +86 -0
- package/dist/tools/search-tools.js.map +1 -0
- package/dist/tools/search-tools.test.d.ts +2 -0
- package/dist/tools/search-tools.test.d.ts.map +1 -0
- package/dist/tools/search-tools.test.js +60 -0
- package/dist/tools/search-tools.test.js.map +1 -0
- package/dist/tools/snap-cuts-to-beats.d.ts +18 -0
- package/dist/tools/snap-cuts-to-beats.d.ts.map +1 -0
- package/dist/tools/snap-cuts-to-beats.js +110 -0
- package/dist/tools/snap-cuts-to-beats.js.map +1 -0
- package/dist/tools/snap-cuts-to-beats.test.d.ts +2 -0
- package/dist/tools/snap-cuts-to-beats.test.d.ts.map +1 -0
- package/dist/tools/snap-cuts-to-beats.test.js +99 -0
- package/dist/tools/snap-cuts-to-beats.test.js.map +1 -0
- package/dist/tools/speed-ramp.d.ts.map +1 -1
- package/dist/tools/speed-ramp.js +2 -1
- package/dist/tools/speed-ramp.js.map +1 -1
- package/dist/tools/stabilize-video.d.ts.map +1 -1
- package/dist/tools/stabilize-video.js +2 -1
- package/dist/tools/stabilize-video.js.map +1 -1
- package/dist/tools/suggest-broll.d.ts +34 -0
- package/dist/tools/suggest-broll.d.ts.map +1 -0
- package/dist/tools/suggest-broll.js +367 -0
- package/dist/tools/suggest-broll.js.map +1 -0
- package/dist/tools/suggest-broll.test.d.ts +2 -0
- package/dist/tools/suggest-broll.test.d.ts.map +1 -0
- package/dist/tools/suggest-broll.test.js +217 -0
- package/dist/tools/suggest-broll.test.js.map +1 -0
- package/dist/tools/text-based-cut.d.ts +33 -0
- package/dist/tools/text-based-cut.d.ts.map +1 -0
- package/dist/tools/text-based-cut.js +172 -0
- package/dist/tools/text-based-cut.js.map +1 -0
- package/dist/tools/text-based-cut.test.d.ts +2 -0
- package/dist/tools/text-based-cut.test.d.ts.map +1 -0
- package/dist/tools/text-based-cut.test.js +32 -0
- package/dist/tools/text-based-cut.test.js.map +1 -0
- package/dist/tools/transcribe.d.ts +1 -1
- package/dist/tools/transition-videos.d.ts +1 -1
- package/dist/tools/transition-videos.d.ts.map +1 -1
- package/dist/tools/transition-videos.js +2 -1
- package/dist/tools/transition-videos.js.map +1 -1
- package/dist/tools/trim-dead-air.d.ts +59 -0
- package/dist/tools/trim-dead-air.d.ts.map +1 -0
- package/dist/tools/trim-dead-air.js +215 -0
- package/dist/tools/trim-dead-air.js.map +1 -0
- package/dist/tools/trim-dead-air.test.d.ts +2 -0
- package/dist/tools/trim-dead-air.test.d.ts.map +1 -0
- package/dist/tools/trim-dead-air.test.js +75 -0
- package/dist/tools/trim-dead-air.test.js.map +1 -0
- package/dist/tools/verify-thumbnail-promise.d.ts +33 -0
- package/dist/tools/verify-thumbnail-promise.d.ts.map +1 -0
- package/dist/tools/verify-thumbnail-promise.js +112 -0
- package/dist/tools/verify-thumbnail-promise.js.map +1 -0
- package/dist/tools/verify-thumbnail-promise.test.d.ts +2 -0
- package/dist/tools/verify-thumbnail-promise.test.d.ts.map +1 -0
- package/dist/tools/verify-thumbnail-promise.test.js +38 -0
- package/dist/tools/verify-thumbnail-promise.test.js.map +1 -0
- package/dist/tools/write-keyword-captions.d.ts +7 -0
- package/dist/tools/write-keyword-captions.d.ts.map +1 -1
- package/dist/tools/write-keyword-captions.js +35 -4
- package/dist/tools/write-keyword-captions.js.map +1 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +75 -11
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/tool-formatters.d.ts +30 -0
- package/dist/ui/tool-formatters.d.ts.map +1 -0
- package/dist/ui/tool-formatters.js +461 -0
- package/dist/ui/tool-formatters.js.map +1 -0
- package/dist/ui/tool-formatters.test.d.ts +2 -0
- package/dist/ui/tool-formatters.test.d.ts.map +1 -0
- package/dist/ui/tool-formatters.test.js +143 -0
- package/dist/ui/tool-formatters.test.js.map +1 -0
- package/package.json +10 -9
package/dist/skills.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,MAAM,sBAAsB,GAAG
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAqC,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA6B9F,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAY3E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAqC,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA6B9F,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAY3E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CA6hB5F;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAO7E"}
|
package/dist/system-prompt.js
CHANGED
|
@@ -70,6 +70,57 @@ ggeditor is for **long-form** and **short-form** video content.
|
|
|
70
70
|
|
|
71
71
|
Motion graphics: simple text + lower-thirds via fusion_comp (Resolve only). VFX, generative video, animation, 3D, particles, complex compositing remain out of scope — if the user asks for those, say so and propose what we CAN do.
|
|
72
72
|
|
|
73
|
+
# You are an editor, not an export pipeline (READ THIS FIRST)
|
|
74
|
+
|
|
75
|
+
**This is the single most important rule. Internalize it.**
|
|
76
|
+
|
|
77
|
+
When a host is connected (host=resolve / host=premiere), you EDIT THE LIVE TIMELINE. The user watches you work in their NLE — cuts appear on the timeline, SFX clips land on audio tracks, captions attach as a sidecar, markers document each decision. The user can play back, scrub, undo with ⌘Z, ask you to tweak, then ask you to tweak again. Render is the FINAL step that happens once — only when the user explicitly says "render" / "export" / "ship it" / equivalent.
|
|
78
|
+
|
|
79
|
+
**You are FORBIDDEN from:**
|
|
80
|
+
- Calling \`render(...)\` mid-edit. The user has not asked for an export.
|
|
81
|
+
- Chaining file-only tools (\`face_reframe\` → \`burn_subtitles\` → \`add_sfx_at_cuts\` → \`normalize_loudness\`) when each step renders a new mp4 the user can't see in their NLE. That's an export pipeline, not an edit. Each step strands the user further from their timeline.
|
|
82
|
+
- Producing a "deliverable" mp4 the user has to import back themselves. If you HAVE to bake a file (Fairlight ops, retimes, reframe, stabilization — see capability matrix), follow with \`import_to_media_pool\` + \`replace_clip\` so the user sees the result land in their timeline.
|
|
83
|
+
|
|
84
|
+
**Tool selection in editing mode:**
|
|
85
|
+
|
|
86
|
+
| Want to do this? | Use this (timeline-native) | NOT this (file-only export) |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| SFX on cuts | \`add_sfx_to_timeline\` | ~~\`add_sfx_at_cuts\`~~ (final-render only) |
|
|
89
|
+
| Captions | \`write_srt\` + \`import_subtitles\` | ~~\`burn_subtitles\`~~ (final-render only) |
|
|
90
|
+
| Cut filler / silence | \`cut_filler_words\` / \`detect_silence\` → \`import_edl\` | (already EDL-based — timeline-friendly) |
|
|
91
|
+
| Re-cut a window | \`text_based_cut\` → \`import_edl\` | (already EDL-based) |
|
|
92
|
+
| Reorder clips | \`reorder_timeline\` → \`import_edl\` | (already EDL-based) |
|
|
93
|
+
| Multi-track / b-roll | \`insert_broll\` | (live API) |
|
|
94
|
+
| Color | \`apply_lut\` / \`set_primary_correction\` / \`copy_grade\` (Resolve) | (live API) |
|
|
95
|
+
| Markers / decisions | \`add_marker\` | (live API) |
|
|
96
|
+
|
|
97
|
+
**The few file-only tools that genuinely have no scriptable equivalent** (Fairlight is closed, no scriptable retimes / face-reframe / stabilization): when you call them, you MUST \`import_to_media_pool\` the result + \`replace_clip\` the source clip on the timeline so the user sees it. The list of unavoidable file-only ops:
|
|
98
|
+
|
|
99
|
+
- \`normalize_loudness\`, \`mix_audio\`, \`clean_audio\`, \`duck_audio\`, \`bleep_words\` (Fairlight closed)
|
|
100
|
+
- \`speed_ramp\` (no scriptable speed curves)
|
|
101
|
+
- \`face_reframe\`, \`stabilize_video\` (no scriptable equivalent)
|
|
102
|
+
- \`burn_subtitles\` (only when the user wants pixel-baked vertical captions — default to sidecar SRT instead)
|
|
103
|
+
- \`loop_match_short\` (only meaningful at final delivery)
|
|
104
|
+
|
|
105
|
+
**\`render(...)\` and \`render_multi_format(...)\` are only called when the user has said "render" / "export" / "ship it".** Not when you've finished a section. Not when the agent thinks the cut is done. Only on explicit user intent.
|
|
106
|
+
|
|
107
|
+
**When host=none** (no NLE attached): the editor-vs-exporter rule is moot — the user has no timeline. File-only tools are the only path. Use them, but say so up front: "No NLE attached — producing standalone mp4s. Open Resolve / Premiere if you want a timeline-native edit you can keep tweaking."
|
|
108
|
+
|
|
109
|
+
# When the user says "make me a YouTube video"
|
|
110
|
+
|
|
111
|
+
This is the orchestrator path — the single broad ask covers everything from cut to upload. Decide what to ship from the source, then run the canonical pipeline; do NOT ask for tool-mechanic details.
|
|
112
|
+
|
|
113
|
+
**Decision tree:**
|
|
114
|
+
|
|
115
|
+
1. **Probe the source** — \`probe_media(input)\` for duration. Check whether \`<cwd>/.gg/brand.json\` exists (see Brand kit section). Read it silently if so; ALL render-time tools should inherit its defaults.
|
|
116
|
+
2. **Triage long-form vs short-form:**
|
|
117
|
+
- duration > 5 min, prompt silent on format → produce BOTH a long-form cut AND 1–3 Shorts via \`find_viral_moments\`. Default behaviour. Tell the user what you're going to ship before starting; don't ask permission.
|
|
118
|
+
- duration > 5 min, prompt explicit ("long-form only", "just the YouTube version") → only the long-form. Skip Shorts.
|
|
119
|
+
- duration ≤ 5 min → short-form pipeline.
|
|
120
|
+
- duration 4–6 min AND prompt silent → ASK once: "Long-form, Shorts, or both?". One question, then run.
|
|
121
|
+
3. **Read the \`youtube-end-to-end\` skill** for the canonical pipeline. It composes long-form-content-edit + short-form-content-edit + chapter-markers + retention pipeline + metadata bundle. Don't re-derive it; the skill is authoritative.
|
|
122
|
+
4. **Always close with the YouTube delivery checklist** (see section below). Title / description / tags / chapters / thumbnail / multi-format. A YouTube cut without metadata isn't shippable.
|
|
123
|
+
|
|
73
124
|
${HOST_BLOCK_TOKEN}
|
|
74
125
|
|
|
75
126
|
cwd=${cwd}
|
|
@@ -98,6 +149,18 @@ cwd=${cwd}
|
|
|
98
149
|
| Punch-in zoom on cuts | NO | NO | punch_in |
|
|
99
150
|
| Keyword-highlighted captions | NO | NO | write_keyword_captions |
|
|
100
151
|
| SFX on cuts (whoosh) | NO | NO | add_sfx_at_cuts |
|
|
152
|
+
| Face-tracked vertical reframe | partial (smart_reframe — Studio only) | NO | face_reframe (MediaPipe + scenedetect) |
|
|
153
|
+
| Music-synced cuts (beat snap) | NO | NO | snap_cuts_to_beats (librosa) |
|
|
154
|
+
| B-roll search (Pexels) | NO | NO | suggest_broll → insert_broll |
|
|
155
|
+
| Auto profanity bleep | NO | NO | bleep_words |
|
|
156
|
+
| Multi-format render (16:9 + 9:16 + 1:1 + 4:5) | NO (one preset at a time) | NO | render_multi_format |
|
|
157
|
+
| YouTube metadata (title/desc/tags/chapters) | NO | NO | generate_youtube_metadata |
|
|
158
|
+
| Long-form → N Shorts orchestration | NO | NO | find_viral_moments + score_clip |
|
|
159
|
+
| Outro card from brand kit | NO scriptable | NO scriptable | generate_outro |
|
|
160
|
+
| Auto-emoji captions | NO | NO | write_keyword_captions(autoEmoji=true) |
|
|
161
|
+
| Text-based cut (delete-list → EDL) | NO | NO | text_based_cut |
|
|
162
|
+
| Trim head/tail dead air (one call) | NO | NO | trim_dead_air |
|
|
163
|
+
| Thumbnail variants (A/B) | NO | NO | compose_thumbnail_variants |
|
|
101
164
|
|
|
102
165
|
# Escape hatch — host_eval
|
|
103
166
|
|
|
@@ -154,6 +217,51 @@ Never ask the host for full timeline state when you only need a few clips. Token
|
|
|
154
217
|
9. **Never invent timecodes** — read get_timeline first.
|
|
155
218
|
10. **Never render until the user says "render".** Render and import_timeline are destructive (overwrite/replace work). Confirm before calling on a non-empty timeline.
|
|
156
219
|
11. **Safety net before destructive ops.** Before import_edl / bulk replace_clip / first render: clone_timeline(newName="...") and save_project. Cheap insurance. Skip only when the user explicitly says "don't clone".
|
|
220
|
+
12. **Lost in the registry?** Call \`search_tools(query="<what you need>")\` instead of re-scanning the prompt. With ~85 tools that's a real token win.
|
|
221
|
+
|
|
222
|
+
# Brand kit (auto-load)
|
|
223
|
+
|
|
224
|
+
If \`<cwd>/.gg/brand.json\` exists, treat it as the channel's render-time defaults. Schema (all fields optional, JSON):
|
|
225
|
+
|
|
226
|
+
channelName, logo, watermark, intro, outro: file paths relative to cwd
|
|
227
|
+
fonts: { heading: "path/to/.ttf", body: "path/to/.ttf" }
|
|
228
|
+
colors: { primary, secondary, accent } — 6-char hex (RRGGBB, no leading #)
|
|
229
|
+
ctaText: "Subscribe for more" — used by generate_outro
|
|
230
|
+
subscribeUrl: "youtube.com/@channel" — surfaced in description templates
|
|
231
|
+
|
|
232
|
+
Behaviour:
|
|
233
|
+
- \`generate_outro\` reads it directly — zero-arg call works once a brand kit is set up.
|
|
234
|
+
- \`compose_thumbnail\` / \`compose_thumbnail_variants\` should default \`fontFile\` to \`brand.fonts.heading\` when present.
|
|
235
|
+
- \`overlay_watermark\` should default to \`brand.watermark\` when present.
|
|
236
|
+
- \`concat_videos\` for assembly should splice \`brand.intro\` and \`brand.outro\` around the main render unless the user opts out.
|
|
237
|
+
- \`generate_youtube_metadata\` can use \`brand.channelName\` to phrase descriptions in the channel's voice.
|
|
238
|
+
|
|
239
|
+
Don't pause to ask the user about typography or logos when a brand kit exists. Don't lecture them about it either — just inherit the defaults silently and mention which fields you used in the final summary.
|
|
240
|
+
|
|
241
|
+
# YouTube delivery (REQUIRED before declaring done)
|
|
242
|
+
|
|
243
|
+
A cut is not a deliverable. A YouTube upload-ready package is. Before you tell the user the run is finished, EVERY long-form deliverable must include:
|
|
244
|
+
|
|
245
|
+
1. **Captions** — sidecar SRT attached (long-form) or burned-in (vertical). Caption everything that has speech.
|
|
246
|
+
2. **Loudness** — normalised to -14 LUFS / -1 dBTP via \`normalize_loudness(platform="youtube")\`. ALWAYS run before render.
|
|
247
|
+
3. **Chapters** — if duration > 5 min, drop YouTube chapter markers. They live both as Resolve markers (purple) AND in the description block.
|
|
248
|
+
4. **Metadata** — \`generate_youtube_metadata(transcript)\` produces the title/description/tags/chapters/hashtags bundle. ALWAYS run before declaring done. Surface the 3 candidate titles to the user; let them pick.
|
|
249
|
+
5. **Thumbnail variants** — \`compose_thumbnail_variants(input, count=3, text=<best title>)\` for A/B testing. YouTube native A/B is now standard.
|
|
250
|
+
6. **Multi-format** — by default, ALSO produce a 9:16 highlight reel (1–3 Shorts via \`find_viral_moments\`) from the same source unless the user opted out. Use \`render_multi_format\` to dispatch the renders.
|
|
251
|
+
7. **Pre-render check** — \`pre_render_check(timelineEmpty=false, expectCaptions=true, loudnessSource=..., loudnessTarget="youtube")\` before the final render. If any finding has \`severity="block"\`, fix it and re-check.
|
|
252
|
+
|
|
253
|
+
The final reply to the user must list the deliverable paths + the metadata bundle in a single structured summary. See the \`youtube-end-to-end\` skill for the canonical reply shape.
|
|
254
|
+
|
|
255
|
+
# Iteration loop
|
|
256
|
+
|
|
257
|
+
Real creator usage is iterative — *"good but tighten the middle"*, *"hook is weak, try another"*, *"use clip B at 2:30 instead"*. Don't assume single-pass.
|
|
258
|
+
|
|
259
|
+
When the user comes back with feedback after a first cut:
|
|
260
|
+
1. **Read existing markers** via \`get_markers\` — they ARE the prior session's intent. Filter by colour / range / contains so you don't drown in them.
|
|
261
|
+
2. **Diff against the user's new ask.** Identify the smallest re-render that satisfies it. The full pipeline is rarely needed.
|
|
262
|
+
3. **Partial re-render.** When only a window changed, re-render that window and \`concat_videos\` it into the existing master, rather than rebuilding from scratch.
|
|
263
|
+
4. **New decisions get new markers.** Always add a marker for what changed ("v2: re-cut hook to start at 03:14 — stronger cold open"). Future-you (or future-them) reads this on resume.
|
|
264
|
+
5. **Brand kit + style presets** survive iterations. Don't reload them each turn; they're part of the stable session context.
|
|
157
265
|
|
|
158
266
|
# Human-in-the-loop pause
|
|
159
267
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAoB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAoB,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAOxC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAe;IACxD,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,OAAO;;OAEF,IAAI,CAAC,IAAI,QAAQ,CAAC,CAAC,WAAW,GAAG,GAAG;aAC9B,CAAC,CAAC,YAAY,UAAU,CAAC,CAAC,cAAc,UAAU,CAAC,CAAC,cAAc,OAAO,CAAC,CAAC,YAAY,WAAW,CAAC,CAAC,qBAAqB;;;;;+BAKvG,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW,EAAE,UAA+B,EAAE;IAClF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,MAAM;SACtB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,OAAO,OAAO,CAAC,CAAC,IAAI,KAAK,GAAG,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IACpD,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO
|
|
1
|
+
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-fades.d.ts","sourceRoot":"","sources":["../../src/tools/add-fades.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"add-fades.d.ts","sourceRoot":"","sources":["../../src/tools/add-fades.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAKrD,QAAA,MAAM,cAAc;;;;;;;iBAelB,CAAC;AAEH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,OAAO,cAAc,CAAC,CAkEhF"}
|
package/dist/tools/add-fades.js
CHANGED
|
@@ -3,6 +3,7 @@ import { dirname, resolve as resolvePath } from "node:path";
|
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { compact, err } from "../core/format.js";
|
|
5
5
|
import { checkFfmpeg, probeMedia, runFfmpeg } from "../core/media/ffmpeg.js";
|
|
6
|
+
import { safeOutputPath } from "../core/safe-paths.js";
|
|
6
7
|
const AddFadesParams = z.object({
|
|
7
8
|
input: z.string().describe("Source video file."),
|
|
8
9
|
output: z.string().describe("Output path."),
|
|
@@ -34,7 +35,7 @@ export function createAddFadesTool(cwd) {
|
|
|
34
35
|
}
|
|
35
36
|
try {
|
|
36
37
|
const inAbs = resolvePath(cwd, input);
|
|
37
|
-
const outAbs =
|
|
38
|
+
const outAbs = safeOutputPath(cwd, output);
|
|
38
39
|
if (inAbs === outAbs) {
|
|
39
40
|
return err("input and output paths are identical", "pick a different output");
|
|
40
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-fades.js","sourceRoot":"","sources":["../../src/tools/add-fades.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"add-fades.js","sourceRoot":"","sources":["../../src/tools/add-fades.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-sfx-at-cuts.d.ts","sourceRoot":"","sources":["../../src/tools/add-sfx-at-cuts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"add-sfx-at-cuts.d.ts","sourceRoot":"","sources":["../../src/tools/add-sfx-at-cuts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAOrD,QAAA,MAAM,kBAAkB;;;;;;;;;iBAoDtB,CAAC;AAEH;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,OAAO,kBAAkB,CAAC,CAwFxF"}
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import { resolve as resolvePath } from "node:path";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { bundledSfxDescriptionList, listBundledSfxNames, resolveSfx } from "../core/bundled-sfx.js";
|
|
3
4
|
import { compact, err } from "../core/format.js";
|
|
4
5
|
import { checkFfmpeg, probeMedia, runFfmpeg } from "../core/media/ffmpeg.js";
|
|
6
|
+
import { safeOutputPath } from "../core/safe-paths.js";
|
|
5
7
|
import { buildSfxOnCutsFilter } from "../core/sfx-on-cuts.js";
|
|
6
8
|
const AddSfxAtCutsParams = z.object({
|
|
7
9
|
input: z.string().describe("Source video / audio (relative resolves to cwd)."),
|
|
8
10
|
sfx: z
|
|
9
11
|
.string()
|
|
10
|
-
.describe(
|
|
12
|
+
.describe(`SFX. Pass a bundled name (synthesised on demand, cached at ~/.gg/sfx-cache/) OR a file path. ` +
|
|
13
|
+
`Bundled names: ${listBundledSfxNames().join(", ")}. ` +
|
|
14
|
+
`For a custom file: stereo wav / mp3, 200 ms–1 s long is typical.`),
|
|
11
15
|
output: z.string().describe("Output file. Re-encoded; uses input video codec passthrough."),
|
|
12
16
|
cutPoints: z
|
|
13
17
|
.array(z.number().min(0))
|
|
14
18
|
.min(1)
|
|
15
|
-
.describe("Timestamps (seconds) where the SFX should fire
|
|
16
|
-
"
|
|
19
|
+
.describe("Timestamps (seconds) where the SFX should fire — RELATIVE TO THE INPUT FILE. ⚠️ If the " +
|
|
20
|
+
"input is a rendered cut (post-`cut_filler_words` / `text_based_cut`), pass the " +
|
|
21
|
+
"`timelineCutPoints` from that tool's result — NOT source-video transcript timestamps. " +
|
|
22
|
+
"Source-space points drift further out of sync after every cut (fine for the first " +
|
|
23
|
+
"~30 s, off by 20+ s by the end of a typical podcast). Closer-than-minSpacingSec hits " +
|
|
24
|
+
"are deduped automatically."),
|
|
17
25
|
sfxGainDb: z
|
|
18
26
|
.number()
|
|
19
27
|
.min(-30)
|
|
@@ -50,22 +58,35 @@ const AddSfxAtCutsParams = z.object({
|
|
|
50
58
|
export function createAddSfxAtCutsTool(cwd) {
|
|
51
59
|
return {
|
|
52
60
|
name: "add_sfx_at_cuts",
|
|
53
|
-
description:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
description: `BAKE SFX into a rendered mp4 — file-only, final-delivery tool. ` +
|
|
62
|
+
`⚠️ When a host (Resolve / Premiere) is connected, prefer ` +
|
|
63
|
+
`\`add_sfx_to_timeline\` instead — it places real audio clips on track A3 so ` +
|
|
64
|
+
`the user hears them on playback and can tune levels in Fairlight. Use this tool ONLY ` +
|
|
65
|
+
`when host=none OR the user has explicitly asked for a final flat mp4. ` +
|
|
66
|
+
`Bundled SFX (synthesised on demand): ${bundledSfxDescriptionList()}. ` +
|
|
67
|
+
`Default gain -8 dB sits below voice; optional -3 to -6 dB voice ducking. Video is ` +
|
|
68
|
+
`copied through untouched.`,
|
|
58
69
|
parameters: AddSfxAtCutsParams,
|
|
59
70
|
async execute(args, ctx) {
|
|
60
71
|
if (!checkFfmpeg())
|
|
61
72
|
return err("ffmpeg not on PATH", "install ffmpeg");
|
|
62
73
|
try {
|
|
63
74
|
const inAbs = resolvePath(cwd, args.input);
|
|
64
|
-
const
|
|
65
|
-
const outAbs = resolvePath(cwd, args.output);
|
|
75
|
+
const outAbs = safeOutputPath(cwd, args.output);
|
|
66
76
|
if (inAbs === outAbs) {
|
|
67
77
|
return err("output and input are identical", "use a different output path");
|
|
68
78
|
}
|
|
79
|
+
// Resolve bundled name OR file path. Synthesises on first cache miss.
|
|
80
|
+
let sfxAbs;
|
|
81
|
+
let sfxInfo;
|
|
82
|
+
try {
|
|
83
|
+
const r = await resolveSfx(args.sfx, cwd, ctx.signal);
|
|
84
|
+
sfxAbs = r.path;
|
|
85
|
+
sfxInfo = { bundled: r.bundled, name: r.name };
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
return err(e.message, "use a bundled SFX name or supply a real file path");
|
|
89
|
+
}
|
|
69
90
|
const probe = probeMedia(inAbs);
|
|
70
91
|
if (!probe)
|
|
71
92
|
return err(`probe failed for ${inAbs}`, "verify file exists and is media");
|
|
@@ -106,7 +127,11 @@ export function createAddSfxAtCutsTool(cwd) {
|
|
|
106
127
|
if (r.code !== 0) {
|
|
107
128
|
return err(`ffmpeg failed: ${tail(r.stderr)}`);
|
|
108
129
|
}
|
|
109
|
-
return compact({
|
|
130
|
+
return compact({
|
|
131
|
+
path: outAbs,
|
|
132
|
+
hits,
|
|
133
|
+
sfx: sfxInfo.bundled ? `bundled:${sfxInfo.name}` : sfxAbs,
|
|
134
|
+
});
|
|
110
135
|
}
|
|
111
136
|
catch (e) {
|
|
112
137
|
return err(e.message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-sfx-at-cuts.js","sourceRoot":"","sources":["../../src/tools/add-sfx-at-cuts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC;IAC9E,GAAG,EAAE,CAAC;SACH,MAAM,EAAE;SACR,QAAQ,CACP,
|
|
1
|
+
{"version":3,"file":"add-sfx-at-cuts.js","sourceRoot":"","sources":["../../src/tools/add-sfx-at-cuts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { AgentTool } from "@kenkaiiii/gg-agent";
|
|
3
|
+
import type { VideoHost } from "../core/hosts/types.js";
|
|
4
|
+
/**
|
|
5
|
+
* add_sfx_to_timeline — drop SFX clips DIRECTLY onto the active timeline's
|
|
6
|
+
* audio track at each cut point. Sibling of `add_sfx_at_cuts` but operates
|
|
7
|
+
* on the live host (Resolve / Premiere) instead of producing a new mp4.
|
|
8
|
+
*
|
|
9
|
+
* Why this exists: `add_sfx_at_cuts` is file-only — it bakes SFX into a
|
|
10
|
+
* rendered mp4. That's right for "ship the final file" workflows but wrong
|
|
11
|
+
* when the user wants the SFX in the timeline so they can keep editing,
|
|
12
|
+
* tune levels in Fairlight, or hear it on playback in Resolve.
|
|
13
|
+
*
|
|
14
|
+
* Mechanics:
|
|
15
|
+
* 1. Resolve the SFX (bundled name → synthesise via ffmpeg / cache;
|
|
16
|
+
* file path → pass through).
|
|
17
|
+
* 2. Get the timeline frame rate (needed to convert seconds → record frames).
|
|
18
|
+
* 3. For each cut point: place the SFX wav at that record frame on the
|
|
19
|
+
* target audio track via `host.insertClipOnTrack(mediaKind="audio")`.
|
|
20
|
+
*
|
|
21
|
+
* Volume / ducking: the inserted clips land at unity gain. Use Fairlight
|
|
22
|
+
* (Resolve) or Audio Mixer (Premiere) to adjust per-clip levels — Fairlight
|
|
23
|
+
* isn't scriptable so we don't try.
|
|
24
|
+
*/
|
|
25
|
+
declare const AddSfxToTimelineParams: z.ZodObject<{
|
|
26
|
+
sfx: z.ZodString;
|
|
27
|
+
cutPoints: z.ZodArray<z.ZodNumber>;
|
|
28
|
+
track: z.ZodOptional<z.ZodNumber>;
|
|
29
|
+
frameRate: z.ZodOptional<z.ZodNumber>;
|
|
30
|
+
minSpacingSec: z.ZodOptional<z.ZodNumber>;
|
|
31
|
+
}, z.core.$strip>;
|
|
32
|
+
export declare function createAddSfxToTimelineTool(host: VideoHost, cwd: string): AgentTool<typeof AddSfxToTimelineParams>;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=add-sfx-to-timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-sfx-to-timeline.d.ts","sourceRoot":"","sources":["../../src/tools/add-sfx-to-timeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGxD;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,QAAA,MAAM,sBAAsB;;;;;;iBA2C1B,CAAC;AAEH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,MAAM,GACV,SAAS,CAAC,OAAO,sBAAsB,CAAC,CAwH1C"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { bundledSfxDescriptionList, listBundledSfxNames, resolveSfx } from "../core/bundled-sfx.js";
|
|
3
|
+
import { compact, err } from "../core/format.js";
|
|
4
|
+
import { checkFfmpeg } from "../core/media/ffmpeg.js";
|
|
5
|
+
/**
|
|
6
|
+
* add_sfx_to_timeline — drop SFX clips DIRECTLY onto the active timeline's
|
|
7
|
+
* audio track at each cut point. Sibling of `add_sfx_at_cuts` but operates
|
|
8
|
+
* on the live host (Resolve / Premiere) instead of producing a new mp4.
|
|
9
|
+
*
|
|
10
|
+
* Why this exists: `add_sfx_at_cuts` is file-only — it bakes SFX into a
|
|
11
|
+
* rendered mp4. That's right for "ship the final file" workflows but wrong
|
|
12
|
+
* when the user wants the SFX in the timeline so they can keep editing,
|
|
13
|
+
* tune levels in Fairlight, or hear it on playback in Resolve.
|
|
14
|
+
*
|
|
15
|
+
* Mechanics:
|
|
16
|
+
* 1. Resolve the SFX (bundled name → synthesise via ffmpeg / cache;
|
|
17
|
+
* file path → pass through).
|
|
18
|
+
* 2. Get the timeline frame rate (needed to convert seconds → record frames).
|
|
19
|
+
* 3. For each cut point: place the SFX wav at that record frame on the
|
|
20
|
+
* target audio track via `host.insertClipOnTrack(mediaKind="audio")`.
|
|
21
|
+
*
|
|
22
|
+
* Volume / ducking: the inserted clips land at unity gain. Use Fairlight
|
|
23
|
+
* (Resolve) or Audio Mixer (Premiere) to adjust per-clip levels — Fairlight
|
|
24
|
+
* isn't scriptable so we don't try.
|
|
25
|
+
*/
|
|
26
|
+
const AddSfxToTimelineParams = z.object({
|
|
27
|
+
sfx: z
|
|
28
|
+
.string()
|
|
29
|
+
.describe(`SFX. Pass a bundled name (synthesised on demand at ~/.gg/sfx-cache/) OR a file path. ` +
|
|
30
|
+
`Bundled names: ${listBundledSfxNames().join(", ")}.`),
|
|
31
|
+
cutPoints: z
|
|
32
|
+
.array(z.number().min(0))
|
|
33
|
+
.min(1)
|
|
34
|
+
.describe("TIMELINE-space timestamps (seconds) where the SFX should fire. ⚠️ These must be " +
|
|
35
|
+
"timeline-relative — NOT source-video timestamps from the transcript. After " +
|
|
36
|
+
"`cut_filler_words` runs, use the `timelineCutPoints` field from its result; passing " +
|
|
37
|
+
"source-space transcript timestamps causes the SFX to drift further out of sync after " +
|
|
38
|
+
"every cut (fine for the first ~30 s, off by 20+ s by the end). Closer-than-" +
|
|
39
|
+
"minSpacingSec hits are deduped."),
|
|
40
|
+
track: z
|
|
41
|
+
.number()
|
|
42
|
+
.int()
|
|
43
|
+
.min(1)
|
|
44
|
+
.optional()
|
|
45
|
+
.describe("Target audio track (1-indexed). Default 3 — keeps A1 (dialogue) and A2 (music) free. " +
|
|
46
|
+
"If the track doesn't exist, run add_track(kind='audio') first."),
|
|
47
|
+
frameRate: z
|
|
48
|
+
.number()
|
|
49
|
+
.positive()
|
|
50
|
+
.optional()
|
|
51
|
+
.describe("Override timeline frame rate. Auto-detected via get_timeline; pass when host_info " +
|
|
52
|
+
"shows an unusual project fps and the agent has it cached."),
|
|
53
|
+
minSpacingSec: z
|
|
54
|
+
.number()
|
|
55
|
+
.min(0)
|
|
56
|
+
.optional()
|
|
57
|
+
.describe("Min spacing between hits. Closer cuts are dropped (avoids 8 stacked whooshes on " +
|
|
58
|
+
"machine-gun edits). Default 0.25 s."),
|
|
59
|
+
});
|
|
60
|
+
export function createAddSfxToTimelineTool(host, cwd) {
|
|
61
|
+
return {
|
|
62
|
+
name: "add_sfx_to_timeline",
|
|
63
|
+
description: `Insert a SFX clip directly onto the active timeline's audio track at each cut point. ` +
|
|
64
|
+
`LIVE host operation \u2014 unlike add_sfx_at_cuts which bakes SFX into a rendered mp4, ` +
|
|
65
|
+
`this drops actual audio clips into Resolve/Premiere so the user hears them on ` +
|
|
66
|
+
`playback and can tune levels in Fairlight. Bundled SFX (synthesised on demand): ` +
|
|
67
|
+
`${bundledSfxDescriptionList()}. Defaults to track A3 (keeps A1 dialogue / A2 music free); ` +
|
|
68
|
+
`pass track= to override. Pair with cut_filler_words / detect_silence cut-point lists.`,
|
|
69
|
+
parameters: AddSfxToTimelineParams,
|
|
70
|
+
async execute(args, ctx) {
|
|
71
|
+
// ffmpeg only required if the user passed a bundled SFX name (we synthesise).
|
|
72
|
+
// For a literal file path, no ffmpeg dep here \u2014 Resolve/Premiere handles import.
|
|
73
|
+
try {
|
|
74
|
+
// Resolve SFX to an absolute path (synthesise bundled name if cache miss).
|
|
75
|
+
let sfxAbs;
|
|
76
|
+
let sfxInfo;
|
|
77
|
+
try {
|
|
78
|
+
const r = await resolveSfx(args.sfx, cwd, ctx.signal);
|
|
79
|
+
sfxAbs = r.path;
|
|
80
|
+
sfxInfo = { bundled: r.bundled, name: r.name };
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
// Bundled-name failures often surface via ffmpeg synthesis errors;
|
|
84
|
+
// surface ffmpeg presence in the fix hint when relevant.
|
|
85
|
+
const msg = e.message;
|
|
86
|
+
const hint = msg.includes("ffmpeg") || msg.includes("Bundled:")
|
|
87
|
+
? checkFfmpeg()
|
|
88
|
+
? "use a bundled SFX name or supply a real file path"
|
|
89
|
+
: "ffmpeg not on PATH \u2014 install ffmpeg or use a literal file path"
|
|
90
|
+
: "use a bundled SFX name or supply a real file path";
|
|
91
|
+
return err(msg, hint);
|
|
92
|
+
}
|
|
93
|
+
// Determine timeline frame rate.
|
|
94
|
+
let fps = args.frameRate;
|
|
95
|
+
if (fps === undefined) {
|
|
96
|
+
try {
|
|
97
|
+
const tl = await host.getTimeline();
|
|
98
|
+
fps = tl.frameRate;
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
return err(`cannot read timeline framerate: ${e.message}`, "open Resolve/Premiere with an active timeline OR pass frameRate=...");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (!fps || fps <= 0) {
|
|
105
|
+
return err("could not determine timeline frame rate", "pass frameRate=24/25/30/60 explicitly");
|
|
106
|
+
}
|
|
107
|
+
// Sort + dedup cut points by minSpacingSec.
|
|
108
|
+
const minSpacing = args.minSpacingSec ?? 0.25;
|
|
109
|
+
const sortedCuts = [...args.cutPoints].sort((a, b) => a - b);
|
|
110
|
+
const filtered = [];
|
|
111
|
+
for (const c of sortedCuts) {
|
|
112
|
+
if (c < 0)
|
|
113
|
+
continue;
|
|
114
|
+
if (filtered.length === 0 || c - filtered[filtered.length - 1] >= minSpacing) {
|
|
115
|
+
filtered.push(c);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (filtered.length === 0) {
|
|
119
|
+
return err("no usable cut points after filtering");
|
|
120
|
+
}
|
|
121
|
+
// Insert each SFX. Track failures per-cut so a single bad insertion
|
|
122
|
+
// doesn't kill the whole batch.
|
|
123
|
+
const track = args.track ?? 3;
|
|
124
|
+
const inserted = [];
|
|
125
|
+
const failed = [];
|
|
126
|
+
for (const atSec of filtered) {
|
|
127
|
+
if (ctx.signal?.aborted) {
|
|
128
|
+
return err("aborted");
|
|
129
|
+
}
|
|
130
|
+
const recordFrame = Math.round(atSec * fps);
|
|
131
|
+
try {
|
|
132
|
+
const r = await host.insertClipOnTrack({
|
|
133
|
+
mediaPath: sfxAbs,
|
|
134
|
+
track,
|
|
135
|
+
recordFrame,
|
|
136
|
+
mediaKind: "audio",
|
|
137
|
+
});
|
|
138
|
+
inserted.push({ atSec: +atSec.toFixed(3), recordFrame, clipId: r.id });
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
|
+
failed.push({ atSec: +atSec.toFixed(3), error: e.message });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (inserted.length === 0) {
|
|
145
|
+
// Surface the first error so the user sees what went wrong (likely
|
|
146
|
+
// missing audio track \u2014 the agent should add_track('audio') first).
|
|
147
|
+
const firstErr = failed[0]?.error ?? "no clips inserted";
|
|
148
|
+
return err(`no SFX clips inserted on track A${track}: ${firstErr}`, `track A${track} may not exist \u2014 run add_track(kind='audio') first, or pick a lower track`);
|
|
149
|
+
}
|
|
150
|
+
return compact({
|
|
151
|
+
ok: true,
|
|
152
|
+
inserted: inserted.length,
|
|
153
|
+
failed: failed.length || undefined,
|
|
154
|
+
track,
|
|
155
|
+
fps,
|
|
156
|
+
sfx: sfxInfo.bundled ? `bundled:${sfxInfo.name}` : sfxAbs,
|
|
157
|
+
// Sample of inserted clips so the agent can quote what landed where.
|
|
158
|
+
sample: inserted.slice(0, 5),
|
|
159
|
+
// Per-failure detail for the agent to retry / diagnose.
|
|
160
|
+
failures: failed.length ? failed.slice(0, 5) : undefined,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
catch (e) {
|
|
164
|
+
return err(e.message);
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=add-sfx-to-timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-sfx-to-timeline.js","sourceRoot":"","sources":["../../src/tools/add-sfx-to-timeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-sfx-to-timeline.test.d.ts","sourceRoot":"","sources":["../../src/tools/add-sfx-to-timeline.test.ts"],"names":[],"mappings":""}
|